[英]Python multiprocessing.Queue not receiving puts from forked processes
我正在創建固定數量的分叉子進程並嘗試讓它們通過multiprocessing.Queue
返回結果。 這導致了一些意想不到的行為。
import multiprocessing
import os
def main():
n_workers = 4
q = multiprocessing.Queue(n_workers)
for i in range(n_workers):
if os.fork() == 0:
print(f"child {i} put {i}")
q.put(i)
print(f"child {i} exiting")
os._exit(0)
for i in range(n_workers):
res = q.get()
print(f"parent got {res}")
print("parent exiting")
if __name__ == "__main__":
main()
當我運行它時,所有的孩子都將他們的結果排入隊列並終止,但父進程掛起:
child 0 put 0 │
child 1 put 1 │
child 2 put 2 │
child 3 put 3 │
child 0 exiting │
child 1 exiting │
child 2 exiting │
child 3 exiting │
parent got 0
問題是在將數據放入隊列后立即調用os._exit(0)
。
多處理文檔解釋了如何將數據添加到隊列中:
當一個對象被放入隊列時,該對象被腌制,后台線程稍后將腌制的數據刷新到底層管道。
因為進程是分叉的,所以調用os._exit(0)
是必要的(而不是sys.exit(0)
),但它不做任何清理。 如果后台線程還沒有刷新數據,就會丟失!
解決方案是調用close()
后跟join_thread()
:
import multiprocessing
import os
def main():
n_workers = 4
q = multiprocessing.Queue(n_workers)
for i in range(n_workers):
if os.fork() == 0:
print(f"child {i} put {i}")
q.put(i)
print(f"child {i} exiting")
q.close() # indicate nothing else will be queued by this process
q.join_thread() # wait for the background thread to flush the data
os._exit(0)
for i in range(n_workers):
res = q.get()
print(f"parent got {res}")
print("parent exiting")
if __name__ == "__main__":
main()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.