91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python collections.deque雙邊隊列的原理

發布時間:2020-10-29 23:55:17 來源:億速云 閱讀:425 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關Python collections.deque雙邊隊列的原理,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

隊列是一種只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。

在Python文檔中搜索隊列(queue)會發現,Python標準庫中包含了四種隊列,分別是queue.Queue / asyncio.Queue / multiprocessing.Queue / collections.deque。

collections.deque

deque是雙端隊列(double-ended queue)的縮寫,由于兩端都能編輯,deque既可以用來實現棧(stack)也可以用來實現隊列(queue)。

deque支持豐富的操作方法,主要方法如圖:

Python collections.deque雙邊隊列的原理

相比于list實現的隊列,deque實現擁有更低的時間和空間復雜度。list實現在出隊(pop)和插入(insert)時的空間復雜度大約為O(n),deque在出隊(pop)和入隊(append)時的時間復雜度是O(1)。

deque也支持in操作符,可以使用如下寫法:

q = collections.deque([1, 2, 3, 4])
print(5 in q) # False
print(1 in q) # True

deque還封裝了順逆時針的旋轉的方法:rotate。

# 順時針
q = collections.deque([1, 2, 3, 4])
q.rotate(1)
print(q) # [4, 1, 2, 3]
q.rotate(1)
print(q) # [3, 4, 1, 2]

# 逆時針
q = collections.deque([1, 2, 3, 4])
q.rotate(-1)
print(q) # [2, 3, 4, 1]
q.rotate(-1)
print(q) # [3, 4, 1, 2]

線程安全方面,通過查看collections.deque中的append()、pop()等方法的源碼可以知道,他們都是原子操作,所以是GIL保護下的線程安全方法。

static PyObject *
deque_append(dequeobject *deque, PyObject *item) {
Py_INCREF(item);
if (deque_append_internal(deque, item, deque->maxlen) < 0)
return NULL;
Py_RETURN_NONE;
}

通過dis方法可以看到,append是原子操作(一行字節碼)。

Python collections.deque雙邊隊列的原理

綜上,collections.deque是一個可以方便實現隊列的數據結構,具有線程安全的特性,并且有很高的性能。

queue.Queue & asyncio.Queue

queue.Queue和asyncio.Queue都是支持多生產者、多消費者的隊列,基于collections.deque,他們都提供了Queue(FIFO隊列)、PriorityQueue(優先級隊列)、LifoQueue(LIFO隊列),接口方面也相同。

區別在于queue.Queue適用于多線程的場景,asyncio.Queue適用于協程場景下的通信,由于asyncio的加成,queue.Queue下的阻塞接口在asyncio.Queue中則是以返回協程對象的方式執行,具體差異如下表:

 queue.Queueasyncio.Queue
介紹同步隊列asyncio隊列
線程安全
超時機制通過timeout參數實現通過asyncio.wait_for()方法實現
qsize()預估的隊列長度(獲取qsize到下一個操作之間,queue有可能被其它的線程修改,導致qsize大小發生變化)準確的隊列長度(由于是單線程,所以queue不會被其它線程修改)
put() / set()put(item, block=True, timeout=None),可以通過設置block是否為True來配置put和set方法是否為阻塞,并且可以為阻塞操作設置最大時長timeout,block為False時行為和put_nowait()方法一致。put()方法會返回一個協程對象,所以沒有block參數和timeout參數,如果需要非阻塞方法,可以使用put_nowait(),如果需要對阻塞方法應用超時,可以使用coroutine asyncio.wait_for()。

multiprocessing.Queue

multiprocessing提供了三種隊列,分別是Queue、SimpleQueue、JoinableQueue。

Python collections.deque雙邊隊列的原理

multiprocessing.Queue既是線程安全也是進程安全的,相當于queue.Queue的多進程克隆版。和threading.Queue很像,multiprocessing.Queue支持put和get操作,底層結構是multiprocessing.Pipe。

multiprocessing.Queue底層是基于Pipe構建的,但是數據傳遞時并不是直接寫入Pipe,而是寫入進程本地buffer,通過一個feeder線程寫入底層Pipe,這樣做是為了實現超時控制和非阻塞put/get,所以Queue提供了join_thread、cancel_join_thread、close函數來控制feeder的行為,close函數用來關閉feeder線程、join_thread用來join feeder線程,cancel_join_thread用來在控制在進程退出時,不自動join feeder線程,使用cancel_join_thread有可能導致部分數據沒有被feeder寫入Pipe而導致的數據丟失。

和threading.Queue不同的是,multiprocessing.Queue默認不支持join()和task_done操作,這兩個支持需要使用mp.JoinableQueue對象。

SimpleQueue是一個簡化的隊列,去掉了Queue中的buffer,沒有了使用Queue可能出現的問題,但是put和get方法都是阻塞的并且沒有超時控制。

關于Python collections.deque雙邊隊列的原理就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沙河市| 航空| 咸丰县| 尉氏县| 读书| 靖宇县| 兴安县| 天峻县| 勃利县| 锡林浩特市| 醴陵市| 濮阳市| 宝丰县| 平原县| 化州市| 霞浦县| 定襄县| 藁城市| 六盘水市| 开远市| 河池市| 六安市| 泽州县| 长武县| 本溪市| 巫溪县| 辽阳县| 河池市| 陵川县| 兴国县| 柞水县| 宽城| 呼伦贝尔市| 上蔡县| 库车县| 内丘县| 招远市| 龙游县| 公主岭市| 玉山县| 哈尔滨市|