0

スレッドのプールがあるとします。このスレッドのプールは、2 つのキューq1と を使用しますq2。からq1新しいアイテムを読み書きしq2ます。がq1空になると、2 つのキューを交換し、q1, q2, = q2, q1両方が空になるまでプロセスを繰り返します。スレッドを同期するために、アイテムを 1 つだけ含む別のキューを使用し、プロセスの最後にこのアイテムを削除します。

これは非常に愚かな方法だと思います。改善のための提案はありますか?

非常に簡単な例がドキュメントにありますが、キューは 1 つしかありません。それが正しい場合、私のソリューションはあまり見栄えがよくありません。

global flag
global lock
global barrier
global q1
global q2
global q
while True:
    if q1.empty():
        flag = False
        barrier.wait() # wait for all the theads to reach this point.
        # execute the code of swapping queues only once
        with lock:
            if not flag:
                flag = True
                if q2.empty():
                    q.get()
                    q.task_done()
                else:
                    q1, q2 = q2, q1

    process_items_in_q1()
4

1 に答える 1

0

あなたのアプローチはうまくいくと思います。あなたがより良いと思うかもしれないし、そうでないかもしれない他の2つはここにあります:

  1. キューを 1 つだけ使用し、N 個のマーカーをプッシュして「レベル」を区切ることができます。ここで、N はスレッドの数です。スレッドがマーカーを読み取るときは、barrier.wait() を呼び出すだけです。すべての N スレッドがレベル間で barrier.wait() を呼び出すことを確実にすることが目標である場合、これで十分です。

  2. または、上記のコードを少し単純化することもできます。2 つのキューの代わりに 2 つのプレーン リストを使用します。すべてのスレッドは から pop されlist1、 に追加されます。Queuelist2のロジックで特別な注意を払う必要はありません。また、「レベル」がそれぞれ比較的大きい場合は、スレッドを作成するコード全体をレベルごとに単純に繰り返し、それらがすべて完了するまで待機することもできます。これにより、一度に 1 レベルのロジックがさらに明確になります。

(最後に、いつものように、これまでのところ、Python でスレッドを使用しても処理能力は向上しないことに注意してください。GIL があります。)

于 2012-12-12T00:35:13.313 に答える