Python多进程:如何让子进程在父进程终止后执行收尾操作?
如何让子进程在父进程终止后执行收尾操作?
问题背景
原本预期以下代码会让主进程终止后,子进程检测到主进程已终止并执行收尾操作,但实际主进程永远无法终止,子进程持续监控主进程;将子进程设为daemon=True时,子进程会随父进程一同终止,无法执行收尾逻辑。环境为CPython 3.10、Linux系统。
import multiprocessing import psutil import time def monitor(pid): while True: time.sleep(1) print(f'monitor process {multiprocessing.current_process().pid} is monitoring pid {pid}') try: info = psutil.Process(pid).memory_full_info() except psutil.NoSuchProcess: print('monitor process detected that the monitored process has terminated') # some important monitor finalization operations here ... break def launch_monitor(): pid = multiprocessing.current_process().pid m = multiprocessing.Process(daemon=False, target=monitor, kwargs={'pid': pid}) m.start() if __name__ == '__main__': launch_monitor() print('monitor launched') time.sleep(1)
问题原因
- 当子进程设置为
daemon=False(默认)时,父进程必须等待所有非守护子进程退出后才会终止。主进程执行完time.sleep(1)后试图退出,但子进程一直在循环运行,导致主进程阻塞等待,形成死循环。 - 若将子进程设为
daemon=True,父进程退出时会直接终止所有守护进程,子进程来不及执行NoSuchProcess捕获块中的收尾操作。
解决方法
在Linux下,通过让主进程强制退出,跳过等待非守护子进程的步骤,使子进程成为孤儿进程被系统接管,继续运行并检测父进程状态。修改后的代码如下:
import multiprocessing import psutil import time import os def monitor(pid): while True: time.sleep(1) print(f'monitor process {multiprocessing.current_process().pid} is monitoring pid {pid}') try: info = psutil.Process(pid).memory_full_info() except psutil.NoSuchProcess: print('monitor process detected that the monitored process has terminated') # 执行重要的收尾操作 break def launch_monitor(): pid = multiprocessing.current_process().pid m = multiprocessing.Process(daemon=False, target=monitor, kwargs={'pid': pid}) m.start() if __name__ == '__main__': launch_monitor() print('monitor launched') time.sleep(1) os._exit(0) # 主进程强制退出,不等待子进程
原理说明
os._exit(0)会直接终止主进程,不会触发Python的退出清理流程(包括等待非守护子进程)。- 父进程终止后,子进程会成为孤儿进程,被系统初始化进程(如
init或systemd)接管,继续正常运行。 - 子进程通过
psutil检测父进程PID时,会捕获到NoSuchProcess异常,从而执行收尾操作后退出。
这种方式完全基于multiprocessing框架实现,无需额外工具。
内容的提问来源于stack exchange,提问作者matanox
相关产品推荐
相关产品推荐

