Python2.7では、multiprocessing.Queueは、関数内から初期化されると、壊れたエラーをスローします。私は問題を再現する最小限の例を提供しています。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import multiprocessing
def main():
q = multiprocessing.Queue()
for i in range(10):
q.put(i)
if __name__ == "__main__":
main()
以下の壊れたパイプエラーをスローします
Traceback (most recent call last):
File "/usr/lib64/python2.7/multiprocessing/queues.py", line 268, in _feed
send(obj)
IOError: [Errno 32] Broken pipe
Process finished with exit code 0
理由がわからない。関数内からQueueオブジェクトを生成できないのは確かに奇妙です。
ここで何が起こるかは、main()
を呼び出すと、Queue
が作成され、その中に10個のオブジェクトが配置されて関数が終了し、Queue
を含む内部の変数とオブジェクトがすべてガベージコレクションされます。しかし、Queue
の最後の数値を送信しようとしているため、このエラーが発生します。
ドキュメントから documentation :
「プロセスが最初にアイテムをキューに入れると、オブジェクトをバッファーからパイプに転送するフィーダースレッドが開始されます。」
put()
は別のスレッドで作成されるため、スクリプトの実行をブロックせず、キュー操作を完了する前にmain()
関数を終了できます。
これを試して :
#!/usr/bin/python
# -*- coding: utf-8 -*-
import multiprocessing
import time
def main():
q = multiprocessing.Queue()
for i in range(10):
print i
q.put(i)
time.sleep(0.1) # Just enough to let the Queue finish
if __name__ == "__main__":
main()
オブジェクトがjoin
に配置されるまで、キューまたはブロックの実行をQueue
する方法が必要です。ドキュメントを参照してください。
Queue.put()を起動すると、暗黙的なスレッドが開始され、データがキューに配信されます。その間、メインアプリケーションは終了し、データの終了ステーションはありません(キューオブジェクトはガベージコレクションされます)。
私はこれを試します:
_from multiprocessing import Queue
def main():
q = Queue()
for i in range(10):
print i
q.put(i)
q.close()
q.join_thread()
if __name__ == "__main__":
main()
_
join_thread()
は、バッファ内のすべてのデータが確実にフラッシュされるようにします。 close()
はjoin_thread()
の前に呼び出す必要があります
@HarryPotFleurによって提案されているtime.sleep(0.1)
を使用した遅延により、この問題は解決されました。しかし、私はpython3でコードをテストしましたが、壊れたパイプの問題はpython3ではまったく発生しません。これはバグとして報告され、後で修正されたと思います。