欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python|隊列Queue

系統 1819 0

一 前言

本文算是一次隊列的學習筆記,Queue 模塊實現了三種類型的隊列,它們的區別僅僅是隊列中元素被取回的順序。在 FIFO 隊列中,先添加的任務先取回。在 LIFO 隊列中,最近被添加的元素先取回(操作類似一個堆棧)。優先級隊列中,元素將保持排序( 使用 heapq 模塊 ) 并且最小值的條目第一個返回。

值得注意的是 Python 2.X 版本中調用隊列需要引用 import Queue 而在Python 3.X版本中則需要 import queue

二 隊列特性

2.1 Queue的常用函數

Queue常用的方法:

          
            qsize() 獲取隊列的元素個數。
put(item [,block[, timeout]]): 往queue中放一個item
get(item [,block[, timeout]]): 從queue中取出一個item,并在隊列中刪除的這個item
          
        

需要特別說明的是:

如果 block 為 True , timeout 為 None( 也是默認的選項 ),那么get()/put()可能會阻塞,直到隊列中出現可用的數據/位置。如果 timeout 是正整數,那么函數會阻塞直到超時N秒,然后拋出一個異常。
如果 block 為 False ,如果隊列無數據,調用get()或者有無空余位置時調用put(),就立即拋出異常(timeout 將會被忽略)。
          
            task_done(): 表示前面排隊的任務已經被完成。被隊列的消費者線程使用。每個 get() 被用于獲取一個任務, 后續調用 task_done() 告訴隊列,該任務的處理已經完成。
join(): 隊列中所有的元素都被接收和處理完畢之前程序一直阻塞。
          
        

在應用程序中,如果主程序調用了join()則當前程序發生阻塞,當隊列中所有的元素都被處理后,將解除阻塞(意味著每個put()進隊列的條目的 task_done() 都被收到)。如果 task_done() 被調用的次數多于放入隊列中的項目數量,將引發 ValueError 異常 。

我們通過程序向隊列添加元素的時候,未完成任務的計數就會增加。每當消費者線程調用 task_done() 時表示這個元素已經被回收,涉及到該元素的業務邏輯已經完成,未完成計數就會減少。當未完成計數降到零的時候,程序便會解除join()阻塞。

2.2 實踐

我們用一個比較經典的案例 生產者和消費者模型,生產者生產饅頭放到隊列,消費者去隊列里面獲取饅頭。

          
            # encoding: utf-8
"""
author: yangyi@youzan.com
time: 2019/8/14 11:20 PM
func:
"""

from multiprocessing import Process, JoinableQueue, Lock
import time
import random

thread_lock = Lock()


def lock_print(msg):
    with thread_lock:
        print (msg)


def consumer(q):
    while True:
        res = q.get(block=True, timeout=3) # 如果為空 則等待3秒超時則報錯退出
        print('消費者拿到了 %s' % res)
        q.task_done()


def producer(q):
    for item in range(4):
        time.sleep(random.randrange(1, 2))
        q.put('饅頭{0}'.format(item))
        print('生產者做好了 %s' %'饅頭{0}'.format(item))
    q.join()
    lock_print("生產結束")


if __name__ == '__main__':
    print('主進程開始')
    q = JoinableQueue()
    pd = Process(target=producer, args=(q,))
    cp = Process(target=consumer, args=(q,))
    cp.daemon = True ## 
    pd.start()
    cp.start()
    pd.join()
    print('主進程結束')
          
        

說明
這里生產者生產饅頭并將饅頭通過 put() 放到全局的隊列中,消費者從使用 get() 隊列中獲取饅頭然后調用 task_done() 通知隊列中的饅頭已經被消費者獲取。

設置 cp.daemon = True 表示消費者進程會隨主進程一起結束而結束。還有一種寫法是

          
            if __name__ == '__main__':
    print('主進程開始')
    q = JoinableQueue()
    pd = Process(target=producer, args=(q,))
    cp = Process(target=consumer, args=(q,))
    pd.start()
    cp.start()
    pd.join()
    cp.join() 
    print('主進程結束')
          
        

cp.join() 會讓消費者進程一直等待生產者往隊列放數據直到設置的超時時間。具體的邏輯需要結合自己程序的實際需求來定,是需要一直等待生產者生產數據還是隨著主進程結束而結束。

三 總結

本文結合前面文章中介紹的多進程中的 守護進程和 join()方法,學習如何使用隊列中的兩個函數 task_done join 。其實還有其他比較多的函數用法,需要深入的學習探索,感興趣的朋友可以動手實踐一下。

推薦閱讀

          
            https://docs.python.org/zh-cn/3/library/queue.html
https://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/chapter2/12_Thread_communication_using_a_queue.html


          
        

本公眾號長期關注于數據庫技術以及性能優化,故障案例分析,數據庫運維技術知識分享,個人成長和自我管理等主題,歡迎掃碼關注。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久九| 亚洲第一中文字幕 | 美女在线视频网站 | 男女全黄做爰视频免费看 | 久久久综合九色合综国产 | 国产三级网站在线观看 | 爱豆在线观看网址91 | 免费 | 五月色播影音在线观看 | 日本jizz| 狠狠干美女 | 日韩精品视频美在线精品视频 | 久久AV亚洲精品一区无码 | 欧美 日产 国产精品 | 日韩在线aⅴ免费视频 | 国产成人综合在线 | 另类综合网 | www.99re | 黄色短视频在线免费观看 | 国产三级成人 | 色综合欧美 | 欧美精品在线一区 | 国产亚洲综合一区二区 | 日韩少妇成熟A片无码专区 黄在线免费观看 | 先锋影音资源网站 | 久草在线观看首页 | 激情五月婷婷 | 精产国产伦理一二三区 | 久久国产精品久久久久久久久久 | 久久久亚洲伊人色综合网站 | 一级黄a| 色花堂国产精品第一页 | 好看的91视频 | 成人国产在线看 | 91精品久久久久久久久久 | 日韩一区二区精品视频 | 亚洲一区二区欧美 | 久草高清视频 | www.av在线免费观看 | 精品一区二区三区免费 | 国产亚洲欧美日韩v在线 | 亚洲国产日韩欧美综合久久 |