僵尸进程介绍
- 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秒')
网友评论