繁体   English   中英

Python 产生一个子子进程,分离并退出

[英]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完成的 这意味着您将安全:

  1. 你在你的父进程中运行Popen
  2. 立即退出父进程

当父进程退出时,子进程由init进程(在 OSX 上launchd )继承,并且仍将在后台运行。

不需要python程序的前两行,这非常有效:

import subprocess
p = subprocess.Popen(['nc', '-l', '8888'],
                     cwd="/",
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)

我正在阅读有关双叉的信息,但不确定这是否有必要

如果您的父进程继续运行并且您需要保护您的孩子免于与父进程一起死亡,则需要这样做。 这个答案显示了如何做到这一点。

双叉的工作原理:

  1. 通过os.fork()创建一个孩子
  2. 在这个子调用Popen()中启动长时间运行的进程
  3. exit child: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM