linux Python生成子进程,分离并退出

bweufnob  于 9个月前  发布在  Linux
关注(0)|答案(3)|浏览(127)

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

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

字符串
os.setsid()更改进程组,我相信这是当父进程退出时让进程继续运行的原因,因为它不再属于同一个进程组。
这是正确的吗?这是一种可靠的执行方式吗?
基本上,我有一个远程控制实用程序,它通过套接字进行通信,并允许远程启动进程,但我必须确保,如果远程控制死亡,它启动的进程继续运行不受影响。
我阅读到了关于双分叉的文章,不确定这是否是必需的和/或子进程。
谢谢.
Ilya

wj8zmpe1

wj8zmpe11#

对于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上测试

e4eetjau

e4eetjau2#

Unix上的popendone using fork。这意味着你将是安全的:
1.在父进程中运行Popen
1.立即退出父进程
当父进程退出时,子进程由init进程(OSX上为launchd)继承,并且仍将在后台运行。
你的python程序的前两行是不需要的,这是完美的工作:

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

字符串
我在阅读有关双叉,不知道这是必要的
如果你的父进程继续运行,你需要保护你的子进程不随父进程一起死亡,这将是必要的。This answer展示了如何做到这一点。
双叉如何工作:
1.通过os.fork()创建子进程
1.在这个子调用Popen()中,它启动了长时间运行的进程

  1. exit child:Popen进程由init继承并在后台运行
    为什么父进程必须立即退出?如果它没有立即退出会发生什么?
    如果你让父进程继续运行,而用户通过ctrl-CSIGINT)或ctrl-\SIGQUIT)停止了该进程,那么它将同时杀死父进程和Popen进程。
    如果它在分叉后一秒退出怎么办?
    然后,在这1 s期间,您的Popen进程容易受到ctrl-c等的攻击。如果您需要100%确定,请使用双分叉。
t1qtbnec

t1qtbnec3#

在Windows上工作:

proc_exe = subprocess.Popen(<Your executable path>, shell=True)
    proc_exe.send_signal(subprocess.signal.SIGTERM)

字符串
subprocess.Popen()的默认父进程将是调用者进程;通常这是一个很好的功能;但在某些情况下,父进程(调用者)的资源将被锁定,直到子进程被终止。subprocess.send_signal()方法将完成这一任务。运行此命令后,子进程()将与父进程断开连接,作为一个进程自行运行。

确保使用“shell=True”选项来调用子进程。

因为send_signal()方法只会终止“CMD.exe”(父进程)而不是实际的调用者。

相关问题