python僵尸进程问题
最近在linux上运行python程序,在主进程未退出,子进程超时,手动结束子进程时,发现子进程留下了僵尸进程,直接解决办法是:在手动terminate之后,还要调join方法。
下面是专项测试:测试文件为terminate_process.py
一、测试子进程正常结束,发现不会留下僵尸进程,子进程结束后马上被回收
二、测试子进程异常,发现不会留下僵尸进程
三、测试子进程超时,即使结束掉子进程,发现会留下僵尸进程
清除僵尸进程
清除僵尸进程至少有三种方法:
- 第一种方法就是结束父进程(一般是主进程)。当父进程退出的时候僵尸进程随后也会被清除。 当然这个是个暴力的手段,因为我们一般肯定是希望父进程继续运行的。
- 第二种方法就是通过 wait 调用来读取子进程退出状态。比如通过 multiprocessing.Process 产出的进程可以通过子进程的 join() 方法来 wait,也可以在父进程中处理 SIGCHLD 信号,在处理程序中调用 wait 系统调用或者直接设置为 SIG_IGN 来清除僵尸进程。
- 第三种办法就说把进程变成孤儿进程,这样进程就会自动交由 init 进程(pid 为 1 的进程)来处理,一般 init 进程都包含对僵尸进程进行处理的逻辑。(这里有个坑,那就是 docker 容器中一般 pid 为 1 进程就是主程序的进程,而不是我们预期的 init 进程。如果要使用这种方法的话,需要注意一下类似的场景)
在我的程序中,我不希望父进程挂掉,那么我采取第二个办法,在terminate()之后继续join一下,发现僵尸进程被清理了,成功解决问题