Python|キューQueue

3665 ワード

はじめに
本文は1回のキューの学習ノートとして、Queueモジュールは3種類のキューを実現して、それらの違いはキューの中の要素が取り戻される順序だけです.FIFOキューでは、追加されたタスクが先にフェッチされます.LIFOキューでは、最近追加された要素が先にフェッチされる(動作はスタックに似ている).優先順位キューでは、要素はソート(heapqモジュールを使用)され、最小値のエントリが最初に返されます.
注目すべきはPython 2.Xバージョンでキューを呼び出すには、Python 3でimport Queueを参照する必要がある.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: [email protected]
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()メソッドを組み合わせて,キュー内の2つの関数task_donejoinの使用方法を学習する.実は他にも多くの関数の使い方があり、深く勉強して探求する必要があります.興味のある友达は実践することができます.
おすすめ読書
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

-The End-
本公衆番号は長期にわたってデータベース技術及び性能最適化、故障事例分析、データベース運営維持技術知識の共有、個人成長と自己管理などのテーマに注目し、スキャンコードの注目を歓迎する.
転載先:https://www.cnblogs.com/yangyi402/p/11413674.html