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
Python spawn off a child subprocess, detach, and exit
提问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
popen
on Unix is done using fork
. That means you'll be safe with:
popen
在 Unix 上是使用fork
. 这意味着您将安全:
- you run
Popen
in your parent process - immediately exit the parent process
- 你
Popen
在你的父进程中运行 - 立即退出父进程
When the parent process exits, the child process is inherited by the init
process (launchd
on OSX) and will still run in the background.
当父进程退出时,子进程由进程继承init
(launchd
在 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:
双叉的工作原理:
- create a child via
os.fork()
- in this child call
Popen()
which launches the long running process - exit child:
Popen
process is inherited byinit
and runs in the background
- 通过创建一个孩子
os.fork()
- 在这个
Popen()
启动长时间运行进程的子调用中 - 退出子
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 Popen
process.
如果您让父进程继续运行并且用户停止进程,例如通过ctrl-C
( SIGINT
) 或ctrl-\
( SIGQUIT
) 那么它会同时终止父进程和Popen
进程。
What if it exits one second after forking?
如果分叉后一秒退出怎么办?
Then, during this 1s period your Popen
process is vulnerable to ctrl-c etc. If you need to be 100% sure then use the double forking.
然后,在这 1 秒期间,您的Popen
进程容易受到 ctrl-c 等攻击。如果您需要 100% 确定,请使用双分叉。