15

私はPythonを初めて使用します(私はPHPから来ました)、チュートリアルを読んで数日間試してみましたが、このキューの例を理解できません(http://docs.python.org/2/library /queue.html )

def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

for item in source():
    q.put(item)

q.join()       # block until all tasks are done

私が理解していないのは、ワーカースレッドがどのように完了して存在するかです。アイテムが利用可能になるまで q.get() ブロックを読んだので、すべてのアイテムが処理され、キューに何も残っていない場合、q.get() が永久にブロックされないのはなぜですか?

4

2 に答える 2

9

このコードでは、スレッドは正常に終了しません (キューが空の場合、スレッドは実際にブロックされます)。それらはデーモンスレッドであるため、プログラムはそれらを待ちません。

q.joinandq.task_done呼び出しのために、プログラムはすぐには終了せず、永久にブロックされません。

アイテムがキューに追加されるたびに、未完了のタスクの数が増えます。task_done()アイテムが取得され、そのアイテムに対するすべての作業が完了したことを示すためにコンシューマ スレッドが呼び出すたびに、カウントは減少します。未完了のタスクの数がゼロになると、join()ブロックが解除され、プログラムはデーモン スレッドを待たずに存在します。

于 2013-03-02T11:34:32.890 に答える
-3

私は同じ問題を抱えていました。すべてのスレッドが完了すると、プロセス リストに「スリープ中のスレッド」が表示されます (スクリプトでプロセス ID のtop -H -p <pid>場所を使用します)。<pid>ps aux | grep python

「無限ループ」while Trueを に置き換えることで、この問題を解決しましたwhile not q.empty():

「眠っているスレッド」の問題を修正しました。

def worker():
    while not q.empty():
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

for item in source():
    q.put(item)

q.join()       # block until all tasks are done
于 2014-01-31T12:06:44.290 に答える