之前的文章中講解很多關(guān)于線程間通信的知識(shí),比如:線程互斥鎖lock,線程事件event,線程條件變量condition?等等,這些都是在開(kāi)發(fā)中經(jīng)常使用的內(nèi)容,而今天繼續(xù)給大家講解一個(gè)更重要的知識(shí)點(diǎn) —?線程隊(duì)列queue。
10年積累的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有臨江免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
1.線程隊(duì)列Queue?— FIFO(先進(jìn)先出隊(duì)列),即哪個(gè)數(shù)據(jù)先存入,取數(shù)據(jù)的時(shí)候先取哪個(gè)數(shù)據(jù),同生活中的排隊(duì)買(mǎi)東西;
2.線程隊(duì)列LifoQueue?— LIFO(先進(jìn)后出隊(duì)列),即哪個(gè)數(shù)據(jù)最后存入的,取數(shù)據(jù)的時(shí)候先取;
3.線程隊(duì)列PriorityQueue?— PriorityQueue(優(yōu)先級(jí)隊(duì)列),即存入數(shù)據(jù)時(shí)候加入一個(gè)優(yōu)先級(jí),取數(shù)據(jù)的時(shí)候優(yōu)先級(jí)最高的取出;
今天只對(duì)第一種普通線程隊(duì)列Queue(FIFO)講解,后面的兩種留到下一篇文章在做詳細(xì)講解!
?
?
線程隊(duì)列Queue,也稱(chēng)FIFO,存在隊(duì)列中的數(shù)據(jù)先進(jìn)先出,就好比拉肚子,吃什么拉什么~~呃呃,有點(diǎn)重口味,如下圖:
?
舉個(gè)形象的例子:如果把123456這6個(gè)數(shù)字,依次放入隊(duì)列queue中,那么我們重隊(duì)列中取數(shù)據(jù)的時(shí)候,取到的第一個(gè)數(shù)據(jù)必然是1,第二個(gè)數(shù)據(jù)必然是2,依次類(lèi)推,這就是所謂的吃什么拉什么 — FIFO(先進(jìn)先出)
?
Queue.qsize() ? 返回隊(duì)列大小
Queue.empty() 判斷隊(duì)列是否為空
Queue.full() ? ? ? 判斷隊(duì)列是否滿(mǎn)了
Queue.get([block[,timeout]]) 從隊(duì)列頭刪除并返回一個(gè)item,block默認(rèn)為T(mén)rue,表示當(dāng)隊(duì)列為空卻去get的時(shí)候會(huì)阻塞線程,等待直到有有item出現(xiàn)為止來(lái)get出這個(gè)item。如果是False的話表明當(dāng)隊(duì)列為空你卻去get的時(shí)候,會(huì)引發(fā)異常。在block為T(mén)rue的情況下可以再設(shè)置timeout參數(shù)。表示當(dāng)隊(duì)列為空,get阻塞timeout指定的秒數(shù)之后還沒(méi)有g(shù)et到的話就引發(fā)Full異常。
?
Queue.task_done() 從場(chǎng)景上來(lái)說(shuō),處理完一個(gè)get出來(lái)的item之后,調(diào)用task_done將向隊(duì)列發(fā)出一個(gè)信號(hào),表示本任務(wù)已經(jīng)完成(與Queue.get配對(duì)使用)。
?
Queue.put(…[,block[,timeout]]) 向隊(duì)尾插入一個(gè)item,同樣若block=True的話隊(duì)列滿(mǎn)時(shí)就阻塞等待有空位出來(lái)再put,block=False時(shí)引發(fā)異常。同get的timeout,put的timeout是在block為T(mén)rue的時(shí)候進(jìn)行超時(shí)設(shè)置的參數(shù)。
?
Queue.join() 監(jiān)視所有item并阻塞主線程,直到所有item都調(diào)用了task_done之后主線程才繼續(xù)向下執(zhí)行。這么做的好處在于,假如一個(gè)線程開(kāi)始處理最后一個(gè)任務(wù),它從任務(wù)隊(duì)列中拿走最后一個(gè)任務(wù),此時(shí)任務(wù)隊(duì)列就空了但最后那個(gè)線程還沒(méi)處理完。當(dāng)調(diào)用了join之后,主線程就不會(huì)因?yàn)殛?duì)列空了而擅自結(jié)束,而是等待最后那個(gè)線程處理完成了。
?
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | # !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解憂 @Blog(個(gè)人博客地址): shuopython.com @WeChat Official Account(微信公眾號(hào)):猿說(shuō)python @Github:www.github.com ? @File:python_queue.py @Time:2019/11/29 15:25 ? @Motto:不積跬步無(wú)以至千里,不積小流無(wú)以成江海,程序人生的精彩需要堅(jiān)持不懈地積累! """ ? importthreading importqueue ? q=queue.Queue(5)??# 長(zhǎng)度,隊(duì)列中最多存放5個(gè)數(shù)據(jù) ? ? defput(): ????foriinrange(20): ????????q.put(i) ????????print("數(shù)字%d存入隊(duì)列成功"%i) ????q.join()??# 阻塞進(jìn)程,直到所有任務(wù)完成,取多少次數(shù)據(jù)task_done多少次才行,否則最后的ok無(wú)法打印 ????print('ok') ? ? defget(): ????foriinrange(20): ????????value=q.get() ????????print("數(shù)字%d重隊(duì)列中取出"%value) ????????q.task_done()??# 必須每取走一個(gè)數(shù)據(jù),發(fā)一個(gè)信號(hào)給join ????# q.task_done()?? #放在這沒(méi)用,因?yàn)閖oin實(shí)際上是一個(gè)計(jì)數(shù)器,put了多少個(gè)數(shù)據(jù), ????# 計(jì)數(shù)器就是多少,每task_done一次,計(jì)數(shù)器減1,直到為0才繼續(xù)執(zhí)行 ? ? t1=threading.Thread(target=put,args=()) t1.start() t2=threading.Thread(target=get,args=()) t2.start() |
輸出結(jié)果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 數(shù)字0存入隊(duì)列成功 數(shù)字1存入隊(duì)列成功 數(shù)字2存入隊(duì)列成功 數(shù)字3存入隊(duì)列成功 數(shù)字4存入隊(duì)列成功 數(shù)字0重隊(duì)列中取出 數(shù)字1重隊(duì)列中取出 數(shù)字2重隊(duì)列中取出 數(shù)字3重隊(duì)列中取出 數(shù)字4重隊(duì)列中取出 數(shù)字5存入隊(duì)列成功 數(shù)字6存入隊(duì)列成功 數(shù)字7存入隊(duì)列成功 數(shù)字8存入隊(duì)列成功 數(shù)字9存入隊(duì)列成功 數(shù)字5重隊(duì)列中取出 數(shù)字6重隊(duì)列中取出 數(shù)字7重隊(duì)列中取出 數(shù)字8重隊(duì)列中取出 數(shù)字9重隊(duì)列中取出 數(shù)字10存入隊(duì)列成功 數(shù)字11存入隊(duì)列成功 數(shù)字12存入隊(duì)列成功 數(shù)字13存入隊(duì)列成功 數(shù)字14存入隊(duì)列成功 數(shù)字10重隊(duì)列中取出 數(shù)字11重隊(duì)列中取出 數(shù)字12重隊(duì)列中取出 數(shù)字15存入隊(duì)列成功 數(shù)字16存入隊(duì)列成功 數(shù)字17存入隊(duì)列成功 數(shù)字13重隊(duì)列中取出 數(shù)字14重隊(duì)列中取出 數(shù)字15重隊(duì)列中取出 數(shù)字16重隊(duì)列中取出 數(shù)字18存入隊(duì)列成功 數(shù)字19存入隊(duì)列成功 數(shù)字17重隊(duì)列中取出 數(shù)字18重隊(duì)列中取出 數(shù)字19重隊(duì)列中取出 ok |
?
?
1.pycharm配置開(kāi)發(fā)模板
2.python字典推導(dǎo)式
3.python列表推導(dǎo)式
4.python匿名函數(shù)lambda
?
轉(zhuǎn)載請(qǐng)注明:猿說(shuō)Python???python線程隊(duì)列Queue-FIFO
?