Python 产生一个子子进程,分离并退出 [英] Python spawn off a child subprocess, detach, and exit

查看:33
本文介绍了Python 产生一个子子进程,分离并退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

os.setsid()os.umask(0)p = subprocess.Popen(['nc', '-l', '8888'],cwd=self.home,标准输出=子进程.PIPE,stderr=subprocess.STDOUT)

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

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

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

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

谢谢.

伊莉雅

解决方案

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

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

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

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

导入子流程p = subprocess.Popen(['nc', '-l', '8888'],cwd="/",标准输出=子进程.PIPE,stderr=subprocess.STDOUT)

<块引用>

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

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

双叉的工作原理:

  1. 通过os.fork()
  2. 创建一个子节点
  3. 在这个子调用 Popen() 中启动长时间运行的进程
  4. exit child:Popen进程被init继承并在后台运行

<块引用>

为什么父级必须立即退出?如果不立即退出会怎样?

如果您让父进程运行而用户停止进程,例如通过 ctrl-C (SIGINT) 或 ctrl- (SIGQUIT) 然后它会杀死父进程和 Popen 过程.

<块引用>

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

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

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...

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.

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?

Thanks.

Ilya

解决方案

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

  1. you run Popen in your parent process
  2. immediately exit the parent process

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

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

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 answer shows 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: Popen process is inherited by init and runs in the background

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.

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.

这篇关于Python 产生一个子子进程,分离并退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆