Python产生子子进程,分离和退出

Ily*_*rin 28 python unix linux subprocess

我不知道这是否是执行系统进程,并从母公司分离的正确途径,但允许家长从退出而不创建一个僵尸和/或杀死子进程.我目前正在使用子进程模块并执行此操作...

os.setsid() 
os.umask(0) 
p = subprocess.Popen(['nc', '-l', '8888'],
                     cwd=self.home,
                     stdout=subprocess.PIPE, 
                     stderr=subprocess.STDOUT)
Run Code Online (Sandbox Code Playgroud)

os.setsid()更改了进程组,我认为这是让进程在父进程退出时继续运行的原因,因为它不再属于同一进程组.

这是正确的,这也是一种可靠的执行方式吗?

基本上,我有一个远程控制实用程序,通过套接字进行通信,允许远程启动进程,但我必须确保如果远程控制器死亡,它启动的进程继续运行不受影响.

我正在阅读关于双叉并且不确定这是否必要和/或subprocess.POpen close_fds以某种方式处理这个问题,所需要的只是更改进程组?

谢谢.

伊利亚

han*_*ast 13

popen在Unix上完成使用fork.这意味着你将安全:

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

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

你的python程序的前两行是不需要的,这完美有效:

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

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

如果您的父进程继续运行并且您需要保护您的孩子不会与父母一起死亡,那么这将是必需的.这个答案说明了如何做到这一点.

双叉如何工作:

  1. 通过创造一个孩子 os.fork()
  2. 在这个Popen()启动长时间运行过程的子调用中
  3. 退出子Popen进程:进程由init后台继承并在后台运行

为什么父母必须立即退出?如果它不立即退出会发生什么?

如果让父进程运行并且用户停止进程,例如通过ctrl-C(SIGINT)或ctrl-\(SIGQUIT),则会终止父进程和Popen进程.

如果它在分叉后退出一秒怎么办?

然后,在这个1s期间,您的Popen过程很容易受到ctrl-c等的影响.如果您需要100%确定,那么请使用双重分叉.

  • 如果子进程将大量输出放入管道,则此进程将挂起。如果您不想与进程通信,请设置 `stdout=None`。有关更多详细信息,请参阅:https://thraxil.org/users/anders/posts/2008/03/13/Subprocess-Hanging-PIPE-is-your-enemy/ (2认同)

JS.*_*JS. 11

对于 Python 3.8.x,过程有点不同。使用start_new_session自 Python 3.2 起可用的参数:

import shlex
import subprocess

cmd = "<full filepath plus arguments of child process>"
cmds = shlex.split(cmd)
p = subprocess.Popen(cmds, start_new_session=True)
Run Code Online (Sandbox Code Playgroud)

这将允许父进程退出而子进程继续运行。不知道僵尸。

start_new_session所有 POSIX 系统都支持该参数,即 Linux、MacOS 等。

在 macOS 10.15.5 上的 Python 3.8.1 上测试

  • `start_new_session=True` 就像魅力一样。如果要抑制输出,请添加这些参数,`stdout=subprocess.DEVNULL`、`stderr=subprocess.STDOUT`。 (3认同)
  • 我可以确认 start_new_session 在 Python 3.7 和 Python 3.2 中有效。在我看来,这是最干净的方法,至少对我来说是这样。 (2认同)