[英]Python spawn off a child subprocess, detach, and exit
我想知道这是否是执行系统进程并与父进程分离的正确方法,尽管允许父进程退出而不创建僵尸和/或杀死子进程。 我目前正在使用 subprocess 模块并执行此操作...
os.setsid()
os.umask(0)
p = subprocess.Popen(['nc', '-l', '8888'],
cwd=self.home,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
os.setsid() 改变了进程组,我相信这是当它的父进程退出时让进程继续运行的原因,因为它不再属于同一个进程组。
这是正确的,也是执行此操作的可靠方法吗?
基本上,我有一个远程控制实用程序,它通过套接字进行通信并允许远程启动进程,但我必须确保如果远程控制死机,它启动的进程继续运行不受影响。
我正在阅读有关双叉的信息,但不确定这是否有必要和/或 subprocess.POpen close_fds 以某种方式解决了这个问题,所需要的只是更改进程组?
谢谢。
伊利亚
Unix 上的popen
是使用fork
完成的。 这意味着您将安全:
Popen
当父进程退出时,子进程由init
进程(在 OSX 上launchd
)继承,并且仍将在后台运行。
不需要python程序的前两行,这非常有效:
import subprocess
p = subprocess.Popen(['nc', '-l', '8888'],
cwd="/",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
我正在阅读有关双叉的信息,但不确定这是否有必要
如果您的父进程继续运行并且您需要保护您的孩子免于与父进程一起死亡,则需要这样做。 这个答案显示了如何做到这一点。
双叉的工作原理:
os.fork()
创建一个孩子Popen()
中启动长时间运行的进程Popen
进程由init
继承并在后台运行为什么父母必须立即退出? 如果它没有立即退出会发生什么?
如果您让父进程保持运行并且用户停止进程,例如通过ctrl-C
( SIGINT
) 或ctrl-\\
( SIGQUIT
) 那么它将杀死父进程和Popen
进程。
如果分叉后一秒退出怎么办?
然后,在这 1 Popen
期间,您的Popen
进程容易受到 ctrl-c 等攻击。如果您需要 100% 确定,请使用双分叉。
对于 Python 3.8.x,过程有点不同。 使用自 Python 3.2 起可用的start_new_session
参数:
import shlex
import subprocess
cmd = "<full filepath plus arguments of child process>"
cmds = shlex.split(cmd)
p = subprocess.Popen(cmds, start_new_session=True)
这将允许父进程退出而子进程继续运行。 不知道僵尸。
所有 POSIX 系统都支持start_new_session
参数,即 Linux、MacOS 等。
在 macOS 10.15.5 上的 Python 3.8.1 上测试
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.