python多線程編程-queue模組和生產者-消費者問題

來源:互聯網
上載者:User

標籤:nbsp   版本   div   max   get   bsp   異常   區別   start   

摘錄python核心編程

本例中示範生產者-消費者模型:商品或服務的生產者生產商品,然後將其放到類似隊列的資料結構中。生產商品中的時間是不確定的,同樣消費者消費商品的時間也是不確定的。

使用queue模組(python2.x版本中,叫Queue)來提供線程間通訊的機制,從而讓線程之間可以分享資料。具體而言,就是建立一個隊列,讓生產者(線程)在其中放入新的商品,而消費者(線程)消費這些商品。

下表是queue模組的部分屬性:

屬性 描述
queue模組的類
Queue(maxsize=0) 建立一個先入先出隊列。如果給定最大值,則在隊列沒有空間時阻塞;否則,為無限隊列
LifoQueue(maxsize=0) 建立一個後入先出隊列。如果給定最大值,則在隊列沒有空間時阻塞;否則,為無限序列
PriorityQueue(maxsize=0) 建立一個優先順序隊列。如果給定最大值,則在隊列沒有空間時阻塞;否則,為無限序列
queue異常
Empty 當對空隊列調用get*()方法時拋出異常
Full 當對已滿的隊列調用put*()方法時拋出異常
queue對象方法
qsize() 返回隊列大小。(由於返回隊列大小時可能被其他線程修改,所以該值為近似值)
empty() 如果隊列為空白,則返回True,否則返回False
full() 如果隊列已滿,則返回True,否則返回False
put(item,block=True,timeout=None) 將item放入隊列。如果block為True(預設值),且timeout為None,則在有可用空間之前阻塞;如果timeout為正值,最多阻塞timeout秒;如果block為False,則拋出Empty異常
put_nowait(item) 和put(item,False)效果相同
get(block=True,timeout=None) 從隊列上取得元素。如果給定了block(非0),則一直阻塞直到有可用的元素為止
get_nowait() 和get(False)效果想用
task_done() 用於表示隊列中的某個元素已執行完成,該方法會被下面的join()使用
join() 在隊列中所有元素執行完畢並調用上面的task_done()訊號前,保持阻塞。

下面的prodcons.py指令碼中使用了queue對象實現了生產者-消費者情境,隨機生產或消費商品,且生產者和消費者獨立、並發的執行線程。注意,這裡使用了在之前章節中改寫的MyThread類。

#python 3.6from random import randintfrom time import sleepfrom queue import Queuefrom myThread import MyThread#將一個對象放入隊列中def writeQ(queue):    print(‘正在為隊列生產………‘)    queue.put(‘商品‘,1)    print(‘當前商品總數:‘,queue.qsize())#消費隊列中的一個對象    def readQ(queue):    val = queue.get(1)    print(‘正在從隊列中消費商品……消費後還剩餘商品:‘,queue.qsize())#模仿生產者。    def writer(queue,loops):    for i in range(loops):        writeQ(queue)        sleep(randint(1,3))#writer的睡眠時間一般比reader短,是為了阻礙 reader從空隊列中擷取對象,換句話說就是使得輪到reader執行時,已存在可消費對象的可能性更大。#模仿消費者    def reader(queue,loops):    for i in range(loops):        readQ(queue)        sleep(randint(2,5))    funcs = [writer,reader]nfuncs = range(len(funcs))def main():    nloops = randint(2,5)#randint 和randrange類似,區別在於,randrange是半開半閉區間,而randint是閉區間    q = Queue(32)        threads = []#類比線程池    for i in nfuncs:        t = MyThread(funcs[i],(q,nloops),funcs[i].__name__)#建立線程        threads.append(t)            for i in nfuncs:        threads[i].start()  #開始執行線程            for i in nfuncs:        threads[i].join()            print(‘結束‘)    if __name__ == ‘__main__‘:    main()

執行效果類似:

PS C:\Users\WC> python E:\Python3.6.3\workspace\prodcons.py開始執行 writer  在: Thu Apr 19 21:06:22 2018正在為隊列生產………開始執行 reader  在: Thu Apr 19 21:06:22 2018當前商品總數: 1正在從隊列中消費商品……消費後還剩餘商品: 0正在為隊列生產………當前商品總數: 1正在從隊列中消費商品……消費後還剩餘商品: 0正在為隊列生產………當前商品總數: 1正在從隊列中消費商品……消費後還剩餘商品: 0正在為隊列生產………當前商品總數: 1正在為隊列生產………當前商品總數: 2writer 結束於: Thu Apr 19 21:06:30 2018正在從隊列中消費商品……消費後還剩餘商品: 1正在從隊列中消費商品……消費後還剩餘商品: 0reader 結束於: Thu Apr 19 21:06:39 2018結束

 

python多線程編程-queue模組和生產者-消費者問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.