亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Python collections.deque雙邊隊列原理詳解

瀏覽:3日期:2022-07-09 09:49:19

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

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

collections.deque

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

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

Python collections.deque雙邊隊列原理詳解

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

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

q = collections.deque([1, 2, 3, 4])print(5 in q) # Falseprint(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是原子操作(一行字節(jié)碼)。

Python collections.deque雙邊隊列原理詳解

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

queue.Queue & asyncio.Queue

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

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

queue.Queue asyncio.Queue 介紹 同步隊列 asyncio隊列 線程安全 是 否 超時機制 通過timeout參數(shù)實現(xiàn) 通過asyncio.wait_for()方法實現(xiàn) qsize() 預估的隊列長度(獲取qsize到下一個操作之間,queue有可能被其它的線程修改,導致qsize大小發(fā)生變化) 準確的隊列長度(由于是單線程,所以queue不會被其它線程修改) put() / set() put(item, block=True, timeout=None),可以通過設置block是否為True來配置put和set方法是否為阻塞,并且可以為阻塞操作設置最大時長timeout,block為False時行為和put_nowait()方法一致。 put()方法會返回一個協(xié)程對象,所以沒有block參數(shù)和timeout參數(shù),如果需要非阻塞方法,可以使用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構建的,但是數(shù)據傳遞時并不是直接寫入Pipe,而是寫入進程本地buffer,通過一個feeder線程寫入底層Pipe,這樣做是為了實現(xiàn)超時控制和非阻塞put/get,所以Queue提供了join_thread、cancel_join_thread、close函數(shù)來控制feeder的行為,close函數(shù)用來關閉feeder線程、join_thread用來join feeder線程,cancel_join_thread用來在控制在進程退出時,不自動join feeder線程,使用cancel_join_thread有可能導致部分數(shù)據沒有被feeder寫入Pipe而導致的數(shù)據丟失。

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

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

總結

通過對比可以發(fā)現(xiàn),上述四種結構都實現(xiàn)了隊列,但是用處卻各有偏重,collections.deque在數(shù)據結構層面實現(xiàn)了隊列,但是并沒有應用場景方面的支持,可以看做是一個基礎的數(shù)據結構。queue模塊實現(xiàn)了面向多生產線程、多消費線程的隊列,asyncio.queue模塊則實現(xiàn)了面向多生產協(xié)程、多消費協(xié)程的隊列,而multiprocessing.queue模塊實現(xiàn)了面向多成產進程、多消費進程的隊列。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 国产精品免费aⅴ片在线观看 | 99视频在线观看视频一区 | 停停五月天 | 免费观看国产大片资源视频 | 久久99亚洲综合精品首页 | 成人小视频免费 | 欧美视屏在线观看 | 亚洲欧美日韩高清一区二区三区 | 2019国内精品久久久久久 | 日韩黄色影院 | 玖玖爱视频在线观看 | 中文字幕日本在线视频二区 | 久热这里只有精品视频6 | 91精品免费不卡在线观看 | 久久a级片| 国内精品视频九九九九 | 2021久久精品国产99国产精品 | 黄色网址大全免费 | 国产视频一二三区 | 国产福利视频在线 | 麻豆爱爱视频 | 国产亚洲精品久久久久久久网站 | 久久综合九色综合97飘花 | 国产在线一区二区 | 黄片毛片在线免费看 | 亚洲国产成人久久一区久久 | 一区在线播放 | 综合天天 | 在线观看91精品国产不卡免费 | 欧美黑人巨大肥婆性视频 | 免费在线观看视频网站 | asian极品呦女爱爱 | 91精品国产高清91久久久久久 | 亚洲在线网 | 日本一级在线 | 欧美黑人换爱交换乱理伦片 | 国产1024观看免费视频 | 国产精品亚洲欧美 | 国产欧美日韩不卡在线播放在线 | 久久天天躁狠狠躁夜夜爽蜜月 | 亚洲成年网站在线777 |