当前位置:首页 > python > 正文内容

父进程退出后如何退出子进程

root6年前 (2020-10-26)python2364

我们知道当子进程推出的时候,父进程会收到 SIGCHLD 信号,从而可以采取相应的操作。但是当父进程退出的时候,系统会把子进程的父进程更改为pid=0的 init 进程,而且子进程不会收到任何信号。而我们经常想在父进程退出的时候,让子进程也推出。在 Python 中可以有如下几种做法。

设置子进程为 daemon

这里的 daemon 和系统的守护进程没有任何关系,是 quitwhenparent_dies 的意思。也就是当父进程退出的时候,会自动尝试关闭 daemon=True 的子进程。

p = multiprocessing.Process(target=foo)
p.daemon = True
p.start()

官方文档

在子进程中设置 PDEATHSIG

在 Linux 中,进程可以要求内核在父进程退出的时候给自己发信号。使用系统调用 prctl。

prctl(PR_SET_PDEATHSIG, SIGHUP);

在 Python中也有对应的包 python-prctl,可以在子进程中这样使用,这样在父进程挂掉的时候,子进程就会收到 SIGHUP 信号:

# apt-get install build-essential libcap-dev
# pip install python-prctl

import signal
import prctl

prctl.set_pdeathsig(signal.SIGHUP)

缺点:只支持 linux

父进程在终止的时候回收子进程

可以使用 atexit.register 在主进程中注册代码:

# pip install psutil


import psutil
import atexit
import os
import signal

@atexit.register
def kill_children():
    print("quitting, press Ctrl-C to force quit")
    current_process = psutil.Process()
    children = current_process.children(recursive=True)
    for child in children:
        print("Child pid is {}".format(child.pid))
        os.kill(child.pid, signal.SIGTERM)

使用 atexit 在收到 SIGTERM 的时候并不能触发,所以最好使用 signal 注册到主进程对应的信号上。

缺点是当使用 kill -9 或者使用 os._exit 的时候不会调用这些函数。


扫描二维码推送至手机访问。

版权声明:本文由一叶知秋发布,如需转载请注明出处。

本文链接:https://zhiqiu.top/?id=23

分享给朋友:

相关文章

python 连接rabbitmq出现的诡异进程盗取消息

python 连接rabbitmq出现的诡异进程盗取消息

本文在py2下执行,由来:    因业务需要,python创建子线程后再次创建子进程(用于执行shell命令)。没错就是在子线程里面创建子进程。都知道py2的坑还是蛮多的。问题出现:在某次运行中出现了...

Python eventlet 模块,Timeout() 控制子程序运行时间

pip install  eventlet #安装依赖包# -*- coding:utf-8 -*- import eventlet import time e...

Popen 使用注意(python)

Popen 的构造函数可以尝试指定一下 close_fds = True意思是不继承主线程的上下文件因为Popen在启动一个进程时容易出现僵尸进程,当主进程死亡时可能会继承主进程的上下文资源...

python简单的加密解密

rsa 是非对称加密公钥加密,私钥解密pip install rsaimport rsa from binascii import b2a_hex, a2b_hex class&nb...

pip 升级到指定版本,但是py2的pip版本务必在20版本以内包含20版本

python3 -m pip install --user --upgrade pip==9.0.3(换成你想要的版本编号)如果python2的只能升级到20+版本。超过会出现不支持的情况...

cmd启动python交互模式 出现UnicodeDecodeError: 'gbk' codec can't decode byte 0x9a in position 533

这是因为在python交互模式的中输出了中文,且是个输出被记录在.python_history中删除历史记录文件C:\Users\Administrator\.python_history...