python判断队列是否为空_[python模块]队列queue
一、隊(duì)列queue
隊(duì)列queue 多應(yīng)用在多線程場(chǎng)景,多線程訪問(wèn)共享變量。
對(duì)于多線程而言,訪問(wèn)共享變量時(shí),隊(duì)列queue的線程安全的。
因?yàn)閝ueue使用了一個(gè)線程鎖(pthread.Lock()),以及三個(gè)條件變量(pthread.condition()),來(lái)保證了線程安全。
總結(jié):隊(duì)列提供了一個(gè)安全可靠的共享數(shù)據(jù)使用方案。隊(duì)列內(nèi)置控制安全的幾個(gè)參數(shù),非用戶使用名稱作用
self.mutex互斥鎖任何獲取隊(duì)列的狀態(tài)(empty(),qsize()等),或者修改隊(duì)列的內(nèi)容的操作(get,put等)都必須持有該互斥鎖。共有兩種操作require獲取鎖,release釋放鎖。同時(shí)該互斥鎖被三個(gè)共享變量同時(shí)享有,即操作conditiond時(shí)的require和release操作也就是操作了該互斥鎖。
self.not_full條件變量
隊(duì)列沒(méi)滿當(dāng)隊(duì)列中有元素添加后,會(huì)通知notify其他等待添加元素的線程,喚醒等待require互斥鎖,或者有線程從隊(duì)列中取出一個(gè)元素后,通知其它線程喚醒以等待require互斥鎖。
self.not_empty條件變量
隊(duì)列不為空線程添加數(shù)據(jù)到隊(duì)列中后,會(huì)調(diào)用self.not_empty.notify()通知其它線程,喚醒等待require互斥鎖后,讀取隊(duì)列。
self.all_tasks_done條件變量
隊(duì)列數(shù)據(jù)全部處理完消費(fèi)者線程從隊(duì)列中g(shù)et到任務(wù)后,任務(wù)處理完成,當(dāng)所有的隊(duì)列中的任務(wù)處理完成后,會(huì)使調(diào)用queue.join()的線程返回,表示隊(duì)列中任務(wù)以處理完畢。###queue的初始化函數(shù)###
def?__init__(self,?maxsize=0):
self.maxsize?=?maxsize
self._init(maxsize)
#?mutex?must?be?held?whenever?the?queue?is?mutating.??All?methods
#?that?acquire?mutex?must?release?it?before?returning.??mutex
#?is?shared?between?the?three?conditions,?so?acquiring?and
#?releasing?the?conditions?also?acquires?and?releases?mutex.
self.mutex?=?_threading.Lock()
#?Notify?not_empty?whenever?an?item?is?added?to?the?queue;?a
#?thread?waiting?to?get?is?notified?then.
self.not_empty?=?_threading.Condition(self.mutex)
#?Notify?not_full?whenever?an?item?is?removed?from?the?queue;
#?a?thread?waiting?to?put?is?notified?then.
self.not_full?=?_threading.Condition(self.mutex)
#?Notify?all_tasks_done?whenever?the?number?of?unfinished?tasks
#?drops?to?zero;?thread?waiting?to?join()?is?notified?to?resume
self.all_tasks_done?=?_threading.Condition(self.mutex)
self.unfinished_tasks?=?0
二、隊(duì)列數(shù)據(jù)存取規(guī)則:數(shù)據(jù)使用方式類名作用示例
FIFO先進(jìn)先出Queue(maxsize)先進(jìn)入隊(duì)列的數(shù)據(jù),先取出
maxsize:>=0
設(shè)置隊(duì)列長(zhǎng)度,0為無(wú)限長(zhǎng)q = queue.Queue()
FILO先進(jìn)后出LifoQueue(maxsize)先進(jìn)入隊(duì)列的數(shù)據(jù),最后取出
maxsize:>=0
設(shè)置隊(duì)列長(zhǎng)度,0為無(wú)限長(zhǎng)q = queue.LifoQueue()
Priority優(yōu)先級(jí)PriorityQueue(maxsize)設(shè)置優(yōu)先標(biāo)志,優(yōu)先取出高標(biāo)志位
maxsize:>=0
設(shè)置隊(duì)列長(zhǎng)度,0為無(wú)限長(zhǎng)q = queue.PriorityQueue()
###例子一:先進(jìn)先出###
import?queue
q?=?queue.Queue()
for?i?in?range(5):
q.put(i)
for?i?in?range(5):
print(q.get(),end="?")
#---結(jié)果---
0?1?2?3?4
###例子二:后進(jìn)先出###
import?queue
q?=?queue.LifoQueue()
for?i?in?range(5):
q.put(i)
for?i?in?range(5):
print(q.get(),end="?")
#---結(jié)果---
4?3?2?1?0
###例子三:按優(yōu)先標(biāo)志位讀取###
#參考其它資料,看到許多講述優(yōu)先級(jí)隊(duì)列的實(shí)現(xiàn),但是我覺(jué)得直接用元組的方式比較簡(jiǎn)單粗暴。
import?queue
p?=?queue.PriorityQueue()
p.put((3,"3"))
p.put((1,"1"))
p.put((4,"4"))
p.put((2,"2"))
for?i?in?range(3):
print(p.get())
#---結(jié)果:按元組索引0排序---
(1,?'1')
(2,?'2')
(3,?'3')
(4,?'4')
###例子四:多元組判斷###
import?queue
p?=?queue.PriorityQueue()
p.put((1,4,"a"))
p.put((2,1,"666"))
p.put((1,3,"4"))
p.put((2,2,"2"))
for?i?in?range(3):
print(p.get())
#-----結(jié)果:元組對(duì)應(yīng)的序號(hào)進(jìn)行比較,主鍵是序號(hào)0,越往后,優(yōu)先度越低。-----
(1,?3,?'4')
(1,?4,?'a')
(2,?1,?'666')
(2,?2,?'2')
三、隊(duì)列的常用方法和屬性:
方法和屬性作用示例
task_done()1、標(biāo)記之前的一個(gè)任務(wù)已經(jīng)完成。
2、由隊(duì)列的消費(fèi)者線程調(diào)用。每一個(gè)get()調(diào)用得到一個(gè)任務(wù),接下來(lái)的task_done()調(diào)用告訴隊(duì)列該任務(wù)已經(jīng)處理完畢。
3、如果當(dāng)前的join()當(dāng)前處于阻塞狀態(tài),當(dāng)前的所有元素執(zhí)行后都會(huì)重啟(意味著收到加入queue的每一個(gè)對(duì)象的task_done()調(diào)用的信息)
join()阻塞:
等待隊(duì)列所有任務(wù)執(zhí)行結(jié)束。
當(dāng)消費(fèi)者線程調(diào)用task_done(),隊(duì)列中未完成的計(jì)數(shù)就會(huì)減少,直至計(jì)數(shù)為0,解除阻塞。
put(item,block,timeout)把對(duì)象item放入隊(duì)列:
item:對(duì)象名稱,必填項(xiàng)。
block:
默認(rèn)是True,如果隊(duì)列滿等待。
設(shè)置成False,如果隊(duì)列滿報(bào)Full異常。
timeout:【block為True是生效】
默認(rèn)是None,如果隊(duì)列滿了等待。
0:不等待,隊(duì)列滿了立即報(bào)Full。
正數(shù)1~:等待相應(yīng)秒數(shù),秒數(shù)到了,隊(duì)列還是滿的,報(bào)錯(cuò)Full。
put_nowait(item)向隊(duì)列里存對(duì)象,不等待,如果隊(duì)列滿了,報(bào)queue.Full錯(cuò)誤
get(block,timeout)從隊(duì)列取出對(duì)象,并把對(duì)象從隊(duì)列中刪除
block:
默認(rèn)是True,隊(duì)列為空等待。
可以變更為False,如果隊(duì)列為空,報(bào)Empty錯(cuò)誤。
timeout:【block為True是生效】
默認(rèn)是None,隊(duì)列為空,等待。
0:不等待,隊(duì)列為空直接報(bào)Empty。
正數(shù)1~:等待相應(yīng)秒數(shù),如果依然為空,則報(bào)Empty
get_nowait()從隊(duì)列里取對(duì)象,不等待,如果隊(duì)列為空,報(bào)queue.Empty錯(cuò)誤
qsize()返回隊(duì)列長(zhǎng)度的近似值。
qsize長(zhǎng)度不做為get和put方法的操作依據(jù)。
empty()隊(duì)列為空返回True
不做為get和put方法的操作依據(jù)。
full()隊(duì)列滿了返回True
不做為get和put方法的操作依據(jù)。
四、隊(duì)列數(shù)據(jù)進(jìn)出規(guī)則實(shí)例 :
也是一個(gè)最簡(jiǎn)單的生產(chǎn)者消費(fèi)者例子。
'''例子一:隊(duì)列基本的進(jìn)出規(guī)則'''
import?queue,time,threading,random
def?productor(name,s):????????????????????????#?生產(chǎn)者函數(shù),向隊(duì)列里放產(chǎn)品
time.sleep(s)
print?('服務(wù)員{}有時(shí)間了'.format(name))
q.put(name)
def?customer():???????????????????????????????#?消費(fèi)者函數(shù),從隊(duì)列里取產(chǎn)品
s?=?q.get()
print?('服務(wù)員{}被叫走了'.format(s))
l?=?[]
q?=?queue.LifoQueue()????????#?后進(jìn)先出,把LifoQueue改成Queue,先進(jìn)先出。
for?i?in?range(5):
n?=?random.randint(1,7)
t?=?threading.Thread(target=productor,args=(i,n))????#?生產(chǎn)線程
l.append(t)
t.start()
for?i?in?l:
i.join()
customer()
#-----運(yùn)行結(jié)果:因?yàn)橛蠷andom,所以結(jié)果不固定,主要觀察消費(fèi)順序。------
服務(wù)員0有時(shí)間了
服務(wù)員0被叫走了
服務(wù)員1有時(shí)間了
服務(wù)員1被叫走了
服務(wù)員4有時(shí)間了
服務(wù)員3有時(shí)間了
服務(wù)員2有時(shí)間了
服務(wù)員2被叫走了
服務(wù)員3被叫走了
服務(wù)員4被叫走了
參考資料:
總結(jié)
以上是生活随笔為你收集整理的python判断队列是否为空_[python模块]队列queue的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android勾选控件_Android中
- 下一篇: websocket python爬虫_p