僵尸进程处理方案

僵尸进程介绍

  • Z(zombie)-僵尸进程(子进程终止,父进程没有wait子进程)

僵尸进程产生原因

  • 僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。(一个进程结束了,但是他的父进程没有等待(调用wait/ waitpid)他,那么他将变成一个僵尸进程)
  • 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

系统为什么需要僵尸进程这种进程状态

由于父进程创建子进程是异步的,双方不知道各自的运行状态,而父进程有的时候需要知道子进程退出时的一些信息,所以 linux提供了一种机制,通过让子进程退出时向父进程发送 SIGCHRD 信号来告知父进程,子进程已经退出了。同时,父进程通过调用 wait 和 waitpid 来获取子进程的退出信息。

僵尸进程的危害

  • 占用系统资源
  • 造成内存泄漏

如何防止僵尸进程

  • 让僵尸进程变成孤儿进程,由init回收,就是让父亲先死
  • 采用信号SIGCHLD通知处理,并在信号处理程序中调用wait函数
  • 让僵尸进程的父进程来回收,父进程每隔一段时间来查询子进程是否结束并回收,调用wait()或者waitpid(),通知内核释放僵尸进程

参考链接

代理进程退出,变成僵死进程原因

  • parent创建代理程序拿到代理程序pid和代理端口,ip,没有wait代理进程
  • 代理进程自杀后parent没有处理信号
graph LR
A[parent父进程] -->|创建| B(代理进程)

解决代理变成僵尸进程方法

  • parent创建一个中间进程process并等待process返回,
  • process作为代理的父进程,来创建代理进程
  • processc创建完代理进程返回代理进程pid,代理端口port,ip,自动退出
  • 此时代理进程变成孤儿进程,被系统init托管,代理进程自杀不会成未僵死进程
graph LR
A[parent父进程] -->|创建| B(process)
B[process] -->|创建| C(代理进程)

代码

import time
import subprocess
from multiprocessing import Process, Queue


def open_test_server(port, q):
    com = '/Users/job/Venvs/test/bin/python {} {}'.format('/Users/job/my_tests/test_server.py', port)
    try:
        test_process = subprocess.Popen(com.split())
        pid = test_process.pid
    except Exception as e:
        test_process = None
        pid = None
        print(e)
    q.put({'pid': pid})


def main(port):
    q = Queue()
    sub_process = Process(target=open_test_server, args=(port, q))
    sub_process.start()
    sub_process.join()
    info = q.get()
    print(info)


if __name__ == '__main__':
    main(12345)
    while True:
        time.sleep(10)
        print('父进程睡了10秒')
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容