Python派生子进程、分离和退出
我想知道这是否是执行系统进程并从父进程分离的正确方法,尽管允许父进程退出而不创建僵尸和/或杀死子进程。我目前正在使用子流程模块并执行此操作Python派生子进程、分离和退出,python,linux,unix,subprocess,Python,Linux,Unix,Subprocess,我想知道这是否是执行系统进程并从父进程分离的正确方法,尽管允许父进程退出而不创建僵尸和/或杀死子进程。我目前正在使用子流程模块并执行此操作 os.setsid() os.umask(0) p = subprocess.Popen(['nc', '-l', '8888'], cwd=self.home, stdout=subprocess.PIPE, stderr=s
os.setsid()
os.umask(0)
p = subprocess.Popen(['nc', '-l', '8888'],
cwd=self.home,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
os.setsid()更改进程组,我认为这是让进程在其父进程退出时继续运行的原因,因为它不再属于同一进程组
这是正确的,也是一种可靠的执行方式吗
基本上,我有一个远程控制实用程序,可以通过套接字进行通信,并允许远程启动进程,但我必须确保如果远程控制死机,它启动的进程将继续运行而不受影响
我读过关于双叉的书,但不确定这是否必要和/或子流程。POpen close_fds会以某种方式处理这一问题,所需的只是更改流程组
谢谢
Ilya
popen
在Unix上是。这意味着您可以安全地使用:
Popen
init
进程继承(OSX上的launchd
),并且仍将在后台运行
python程序的前两行不需要,这非常有效:
import subprocess
p = subprocess.Popen(['nc', '-l', '8888'],
cwd="/",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
我在读关于双叉的书,不确定这是否必要
如果您的父进程一直在运行,并且您需要保护您的孩子不与父进程一起死亡,则需要这样做。展示了如何做到这一点
双叉的工作原理:
os.fork()
Popen()
启动长时间运行的进程Popen
进程由init继承并在后台运行
ctrl-C
(SIGINT
)或ctrl-\
(SIGQUIT
)停止进程,则会同时终止父进程和Popen
进程
如果它在分叉后一秒钟退出呢
然后,在这1s期间,您的
Popen
进程容易受到ctrl-c等的攻击。如果您需要100%确定,请使用双分叉。对于Python 3.8.x,该进程有点不同。使用Python 3.2中提供的start\u new\u 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)
导入shlex
导入子流程
cmd=“”
cmds=shlex.split(cmd)
p=subprocess.Popen(cmds,start\u new\u session=True)
这将允许父进程退出,同时子进程继续运行。对僵尸不太清楚
所有POSIX系统,即Linux、MacOS等都支持start\u new\u session
参数
在macOS 10.15.5上的Python3.8.1上进行了测试看一看您能解释为什么父级必须立即退出吗?如果不立即退出会发生什么?什么构成“立即”?如果它在分叉后一秒钟退出怎么办?@Hubro:我已经在上面的回答中添加了您问题的答案,并且还澄清了一些解释不好的事情。如果子进程将大量输出放入管道中,该进程将挂断。如果不想与进程通信,请设置
stdout=None
。有关更多详细信息,请参阅:我可以确认start_new_会话在Python3.7和Python3.2中工作。在我看来,这是最干净的方法,至少对我来说是这样。我应该澄清一下,它在Debian 10和Python 3.7.3中适用于我。start\u new\u session=True
非常有效。如果要抑制输出,请添加以下参数,stdout=subprocess.DEVNULL
,stderr=subprocess.stdout
。