我在i
python中有以下代码,其中子进程尝试执行sys.exit(…)但导致父进程挂起.这是一个错误吗?知道如何解决这个问题吗?
In [1]: from multiprocessing import Pool
In [2]: def f():
...: import sys
...: sys.exit('exiting system...')
...:
In [3]: p = Pool(processes=2)
In [4]: r = p.apply_async(f, [])
In [5]: r.get() <---- it is hanging here forever.
我也尝试过提高SystemExit(…)而不是sys.exit(…),但它是一样的.我知道的唯一解决方法是将加注异常(…)结果正常工作.
我知道sys.exit与提升SystemExit基本相同,但是这个异常应该委托给它的父进程,因此r.get()应该能够正确接收这个异常吗?但它似乎陷入了recv电话.这是多处理模块中的错误吗?
最佳答案 当您调用sys.exit()时,您正在使Pool worker进程实际退出. SystemExit异常是特殊的;当你举起它时,你在退出时提出它的过程.异常不会传播给调用者.因此,这意味着在您的示例中,工作进程根本不会将任何内容返回给父进程.然后父进程将永远等待孩子返回永远不会返回的东西.有关该行为的更深入讨论,请参见
this question.
我认为这是一个错误,并且当子进程退出时,池应该被标记为已损坏,并且所有未完成的任务都应该被中止.这就是concurrent.futures.ProcessPoolExecutor
的表现.我实际上submitted a patch将此行为添加到multiprocessing.Pool,但到目前为止它还没有被审查.
现在,回到原来的问题.看起来您希望父进程退出此处,而不仅仅是子进程.要做到这一点,您需要实际将一些对象返回给父对象,然后在接收到该对象时让父对象退出.看起来你已经发现你可以通过简单地提出异常来做到这一点.