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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5772873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:48:35  来源:igfitidea点击:

Python spawn off a child subprocess, detach, and exit

pythonlinuxunixsubprocess

提问by Ilya Sterin

I'm wondering if this is the correct way to execute a system process and detach from parent, though allowing the parent to exit without creating a zombie and/or killing the child process. I'm currently using the subprocess module and doing this...

我想知道这是否是执行系统进程并与父进程分离的正确方法,尽管允许父进程退出而不创建僵尸和/或杀死子进程。我目前正在使用 subprocess 模块并执行此操作...

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

os.setsid() changes the process group, which I believe is what lets the process continue running when it's parent exits, as it no longer belongs to the same process group.

os.setsid() 改变了进程组,我相信这是当它的父进程退出时让进程继续运行的原因,因为它不再属于同一个进程组。

Is this correct and also is this a reliable way of performing this?

这是正确的,也是执行此操作的可靠方法吗?

Basically, I have a remote control utility that communicate through sockets and allows to start processes remotely, but I have to ensure that if the remote control dies, the processes it started continue running unaffected.

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

I was reading about double-forks and not sure if this is necessary and/or subprocess.POpen close_fds somehow takes care of that and all that's needed is to change the process group?

我正在阅读有关双叉的信息,但不确定这是否有必要和/或 subprocess.POpen close_fds 以某种方式解决了这个问题,所需要的只是更改进程组?

Thanks.

谢谢。

Ilya

伊利亚

回答by hansaplast

popenon Unix is done using fork. That means you'll be safe with:

popen在 Unix 上是使用fork. 这意味着您将安全:

  1. you run Popenin your parent process
  2. immediately exit the parent process
  1. Popen在你的父进程中运行
  2. 立即退出父进程

When the parent process exits, the child process is inherited by the initprocess (launchdon OSX) and will still run in the background.

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

The first two lines of your python program are not needed, this perfectly works:

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

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

I was reading about double-forks and not sure if this is necessary

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

This would be needed if your parent process keeps running and you need to protect your children from dying with the parent. This answershows how this can be done.

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

How the double-fork works:

双叉的工作原理:

  1. create a child via os.fork()
  2. in this child call Popen()which launches the long running process
  3. exit child: Popenprocess is inherited by initand runs in the background
  1. 通过创建一个孩子 os.fork()
  2. 在这个Popen()启动长时间运行进程的子调用中
  3. 退出子Popen进程:进程被继承init并在后台运行

Why the parent has to immediately exit? What happens if it doesn't exit immediately?

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

If you leave the parent running and the user stops the process e.g. via ctrl-C(SIGINT) or ctrl-\(SIGQUIT) then it would kill both the parent process and the Popenprocess.

如果您让父进程继续运行并且用户停止进程,例如通过ctrl-C( SIGINT) 或ctrl-\( SIGQUIT) 那么它会同时终止父进程和Popen进程。

What if it exits one second after forking?

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

Then, during this 1s period your Popenprocess is vulnerable to ctrl-c etc. If you need to be 100% sure then use the double forking.

然后,在这 1 秒期间,您的Popen进程容易受到 ctrl-c 等攻击。如果您需要 100% 确定,请使用双分叉。