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