私は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)を使用しています。
基になるパイプがいっぱいであるように見えるため、フィーダースレッドはパイプへの書き込みをブロックします(実際には、パイプを同時アクセスから保護するロックを取得しようとしたとき)。
この問題を確認してください http://bugs.python.org/issue8237
pythonマルチプロセッシング:一部の関数は完了しても返されません(キューマテリアルが大きすぎます) 任意の関数セットの並列実行で「参加する前に「デキュー」する」という意味を実装します、その戻り値はキューに入れられます。
したがって、これにより、任意のサイズのものをキューに入れることができるため、見つけた制限が邪魔になりません。
デフォルトでは、キューの最大サイズは無限ですが、それをオーバーライドしました。あなたの場合、worker_pはアイテムをキューに入れているので、joinを呼び出す前にキューを解放する必要があります。詳細については、以下のリンクを参照してください。 https://docs.python.org/2/library/multiprocessing.html#programming-guidelines