已调用join()的进程调用Process.close为何仍报错?
问题分析与解决方案
你遇到的核心矛盾是:明明调用了p.join(),但p.close()仍报错进程还在运行。这是因为你的错误处理逻辑存在漏洞,且join()无法保证在所有场景下都能等待进程终止。
关键原因
multiprocessing.Process.join()的语义是等待进程终止,但以下场景会导致join()返回后进程仍存活:
- Daemon线程被强制中断:你的
waiter线程是daemon线程,若主进程的非daemon线程全部退出,主进程会直接终止所有daemon线程,此时waiter线程中的p.join()被中断,但子进程仍在运行。后续你在except块中调用的p.join()可能因主进程即将退出,未真正等待到进程终止就返回。 - 进程进入无法自动终止的状态:如果
myfunc是一个无限循环或因资源锁死无法退出的逻辑,join()会一直阻塞,但你可能通过外部信号(如Ctrl+C)强制触发了CancelledError,导致join()未完成等待就进入后续逻辑。 - 竞态条件:极端情况下,
p.join()完成后到p.is_alive()检查的间隙中,进程状态出现异常更新(概率极低,但存在理论可能)。
修复代码
正确的处理逻辑应该是:主动终止存活的进程,等待其彻底结束后再调用close():
try: await result except asyncio.CancelledError: if p.is_alive(): p.terminate() # 先主动终止进程 p.join() # 等待进程彻底结束 p.close() # 此时进程已终止,可安全调用close
逻辑说明
- 先判断进程是否存活,若存活则调用
terminate()强制终止(也可根据需求用kill()发送更强制的信号)。 - 调用
join()确保进程彻底终止后,再调用close()释放进程关联的资源,从根本上避免了进程运行时调用close()的情况。
内容的提问来源于stack exchange,提问作者user48956
相关产品推荐
相关产品推荐

