这是关于multiprocessing
5中Python 3.
模块的另一个问题。我的问题是我知道所有分叉处理完成了他们的工作(我可以在Queue
看到他们的结果),AsyncResult.result()返回True,这意味着作业已完成,但是当我继续使用PoolObj.join时(),它需要永远。我知道我可以使用PoolObj.terminate()并继续我的生活,但我想知道为什么会发生这种情况?
我使用以下代码:
def worker(d):
queue.put(d)
def gen_data():
for i in range(int(1e6)):
yield i
if __name__ == "__main__":
queue = Queue(maxsize=-1)
pool = Pool(processes=12)
pool_obj_worker = pool.map_async(worker, gen_data(), chunksize=1)
pool.close()
print ('Lets run the workers...\n')
while True:
if pool_obj_worker.ready():
if pool_obj_worker.successful():
print ('\nAll processed successfully!') # I can see this quickly, so my jobs are done
else:
print ('\nAll processed. Errors encountered!')
sys.stdout.flush()
print (q.qsize()) # The size is right that means all workers have done their job
pool.join() # will get stuck here for long long time
queue.put('*')
break
print ('%d still to be processed' %
pool_obj_worker._number_left)
sys.stdout.flush()
time.sleep(0.5)
我做错了吗?请赐教。或者持有join()
的进程是否已经僵尸?
答案 0 :(得分:2)
这里的问题是你在工作中使用了额外的Queue
,而不是Pool
所使用的那个。{1}}。
当进程完成他们的工作时,他们都将加入FeederThread
中使用的multiprocessing.Queue
并且这些调用将挂起(可能是因为所有线程同时调用join
并且可能会有一些奇怪的种族条件,调查并不容易。)
添加multiprocessing.util.log_to_stderr(10)
允许在加入队列馈线线程时显示您的进程挂起。
要解决您的问题,您可以使用multiprocessing.SimpleQueue
代替multiprocessing.Queue
(因为没有支线线程而没有挂起,或者尝试使用提供相同功能的方法pool.unordered_imap
你似乎实现的行为(给一个包含worker返回的结果的无序生成器)。