Python回收进程,防止僵尸进程的出现

通过信号回收子进程,防止出现僵尸进程
子进程退出时向父进程发送SIGCHILD信号
父进程处理SIGCHILD信号
在信号处理函数中调用 os.waitpid(-1, os.WNOHANG)

# sig.py
from multiprocessing import Process
import logging
import os
import signal
import time

logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)-15s - %(levelname)s - %(message)s'
)


def run():
    exitcode = 3
    logging.info("this is run")
    time.sleep(10)
    logging.info("run exit")
    os._exit(exitcode)

def run233():
    logging.info("this is run233")
    time.sleep(20)
    logging.info("run2333 exit")
    
def wait_child(*args):
    print("+++++++++++ wait_child")
    # 一会实验的时候,要改动这里
    cpid, status = os.waitpid(-1, os.WNOHANG)
    print(pid, status)
    #while True:
    #    cpid, status = os.waitpid(-1, os.WNOHANG)
    #    print(cpid, status)
    #    exitcode = status >> 8
    #    print(exitcode)
    #    #break
    #    break


# 添加一个处理信号的程序,每当有子进程退出,都会执行wait_child
signal.signal(signal.SIGCHLD, wait_child)

p = Process(target=run)
p.start()
p1 = Process(target=run233)
p1.start()

print("p",p.pid,"  p1",p1.pid)
#p.join()
#p1.join()
#print("join end")



while True:
    time.sleep(25)
    break
# 开启2个会话

# 一个监听python进程
watch -n 1 -c 'ps -ef | grep python'

# 另一个我们的python代码
python sig.py

# 观察监听python进程的变化
cpid, status = os.waitpid(-1, os.WNOHANG)
第一次实验 有这句话
第二次实验注释掉这句话
第三次实验注释掉这句话,然后在p和p1 start()后加上p.join()  p1.join()
第四次实验,加上json(),在加上这句话。


重点观察
1.进程的是否退出(python sig.py进程个数)
2.是否出现僵尸进程  [python] 
3.加入p.json()前后 观察wait_child 函数中打印的信息

 [python]   这个进程是kill 不掉的
 可以尝试增加主进程sleep时间,然后再开一个终端去kill -9 这个僵尸进程。

使用 json直接回收

p.join(timeout=5.5)   # 阻塞等待回收子进程,5.5秒没结束会产生僵尸进程
if p.is_alive:        # 判断是否存活
    p.terminate()     # 强制结束正在执行的子进程
    p.join()          # 回收子进程

你可能感兴趣的:(Python)