web-dev-qa-db-ja.com

マルチプロセッシングの最大サイズ。キューアイテム?

私はPythonでかなり大規模なプロジェクトに取り組んでおり、メインサービスの速度が低下しないように、計算量の多いバックグラウンドタスクの1つを別のコアにオフロードする必要があります。 _multiprocessing.Queue_を使用してワーカープロセスからの結果を伝達すると、明らかに奇妙な動作に遭遇しました。比較のために_threading.Thread_と_multiprocessing.Process_の両方に同じキューを使用すると、スレッドは正常に機能します。ただし、大きなアイテムをキューに入れた後、プロセスは参加できません。次の点に注意してください。

_import threading
import multiprocessing

class WorkerThread(threading.Thread):
    def __init__(self, queue, size):
        threading.Thread.__init__(self)
        self.queue = queue
        self.size = size

    def run(self):
        self.queue.put(range(size))


class WorkerProcess(multiprocessing.Process):
    def __init__(self, queue, size):
        multiprocessing.Process.__init__(self)
        self.queue = queue
        self.size = size

    def run(self):
        self.queue.put(range(size))


if __name__ == "__main__":
    size = 100000
    queue = multiprocessing.Queue()

    worker_t = WorkerThread(queue, size)
    worker_p = WorkerProcess(queue, size)

    worker_t.start()
    worker_t.join()
    print 'thread results length:', len(queue.get())

    worker_p.start()
    worker_p.join()
    print 'process results length:', len(queue.get())
_

これは_size = 10000_で正常に機能することを確認しましたが、_size = 100000_ではworker_p.join()でハングします。 _multiprocessing.Process_インスタンスが_multiprocessing.Queue_に配置できるものに固有のサイズ制限はありますか?それとも私はここでいくつかの明白で根本的な間違いを犯していますか?

参考までに、Ubuntu10.04ではPython 2.6.5)を使用しています。

17
Brendan Wood

基になるパイプがいっぱいであるように見えるため、フィーダースレッドはパイプへの書き込みをブロックします(実際には、パイプを同時アクセスから保護するロックを取得しようとしたとき)。

この問題を確認してください http://bugs.python.org/issue8237

18
Maksym Polshcha

pythonマルチプロセッシング:一部の関数は完了しても返されません(キューマテリアルが大きすぎます) 任意の関数セットの並列実行で「参加する前に「デキュー」する」という意味を実装します、その戻り値はキューに入れられます。

したがって、これにより、任意のサイズのものをキューに入れることができるため、見つけた制限が邪魔になりません。

2
CPBL

デフォルトでは、キューの最大サイズは無限ですが、それをオーバーライドしました。あなたの場合、worker_pはアイテムをキューに入れているので、joinを呼び出す前にキューを解放する必要があります。詳細については、以下のリンクを参照してください。 https://docs.python.org/2/library/multiprocessing.html#programming-guidelines

2
YATIN KAREL