我想知道这是否是执行系统进程和从父进程分离的正确方法,但允许父进程退出而不创建僵尸和/或终止子进程。我目前正在使用子进程模块并执行此操作...
os.setsid()
os.umask(0)
p = subprocess.Popen(['nc', '-l', '8888'],
cwd=self.home,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
os.setsid()更改了进程组,我相信这是让进程在父进程退出时继续运行的原因,因为它不再属于同一个进程组。
这是否正确,这也是执行此操作的可靠方法吗?
基本上,我有一个通过套接字进行通信并允许远程启动进程的远程控制实用程序,但我必须确保如果远程控制器死亡,它启动的进程将继续不受影响地运行。
我正在读关于双叉并且不确定这是否必要和/或subprocess.POpen close_fds以某种方式解决了这个问题,所需要的只是更改进程组?
感谢。
伊利亚安德
答案 0 :(得分:8)
popen
是done using fork
。这意味着您将安全:
Popen
当父进程退出时,子进程将由init
进程(OSX上的launchd
)继承,并仍将在后台运行。
不需要你的python程序的前两行,这完全有效:
import os, time
import subprocess
p = subprocess.Popen(['nc', '-l', '8888'],
cwd="/",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
我正在阅读关于双叉的信息,不确定是否有必要
如果您的父进程一直在运行,并且您需要保护您的孩子免于与父母一起死亡,则需要这样做。 This answer显示了如何做到这一点。
双叉如何工作:
os.fork()
Popen()
中启动了长时间运行的过程Popen
进程由init
继承并在后台运行为什么父母必须立即退出?如果它没有立即退出会发生什么?
如果你让父母继续运行而且用户停止了这个过程,例如通过ctrl-C
(SIGINT
)或ctrl-\
(SIGQUIT
),它会同时取消父进程和Popen
进程。
分叉后一秒退出怎么办?
然后,在此1s期间,您的Popen
进程容易受到ctrl-c等的影响。如果您需要100%确定,请使用双重分叉。
答案 1 :(得分:1)
对于Python 3.8.x,此过程有些不同:
import shlex
import subprocess
cmd = "<full filepath plus arguments of child process>"
cmds = shlex.split(cmd)
p = subprocess.Popen(cmds, start_new_session=True)
这将允许父进程在子进程继续运行时退出。不确定僵尸。
在macOS 10.15.5上的Python 3.8.1上进行了测试