Python多处理和子进程的独立性

Zag*_*ags 9 python children subprocess multiprocessing orphan

从python终端,我运行如下命令,以产生一个长时间运行的子进程:

from multiprocessing.process import Process
Process(target=LONG_RUNNING_FUNCTION).start()
Run Code Online (Sandbox Code Playgroud)

这个命令返回,我可以在python终端中做其他事情,但是孩子打印的任何内容仍然会打印到我的python终端会话中.

当我退出终端(使用exitCTRL+ D)时,退出命令会挂起.如果我在此挂起期间按CTRL+ C,则终止子进程.

如果我手动终止python终端进程(通过posix kill命令),子进程将被孤立,并继续运行,其输出可能被丢弃.

如果我运行此代码python -c,它等待孩子终止,并且CTRL+ C杀死父和子.

当父母被终止时,哪些运行配置的python会杀死孩子?特别是,如果python-mod_wsgi-apache webserver产生子进程然后重新启动,那么这些孩子会被杀死吗?

[顺便说一下,分离终端产生的子进程的正确方法是什么?有没有比以下更优雅的方式:故意在python中创建一个孤儿进程 ]

更新:在apache重新启动时,multiprocessing.Process由apache下运行的Web服务器生成的python子进程不会被终止.

Alp*_*Alp 14

这不是你如何调用python的问题; 这是该multiprocessing模块的一个功能.导入该模块时,将退出处理程序添加到父进程,该进程在允许父进程退出之前调用所有创建join()的子Process对象multiprocessing.Process.如果您打算以这种方式启动子进程,那么在没有攻击模块内部的情况下,就没有办法避免让您遇到麻烦的行为.

如果你想开始一个能够比父母更活跃的过程,那么你可能会更好地使用它subprocess.Popen.如果孩子以这种方式开始,父母将不会在退出前尝试加入孩子,而是立即退出,留下一个孤儿:

>>> from subprocess import Popen
>>> Popen(["sleep", "100"])
<subprocess.Popen object at 0x10d3fedd0>
>>> exit()
alp:~ $ ps -opid,ppid,command | grep sleep | grep -v grep
37979     1 sleep 100
Run Code Online (Sandbox Code Playgroud)

您使用的是否有特殊原因multiprocessing而不是subprocess?前者不是用来创建意图比父母长寿的子过程; 它是用于创建子进程以执行可以跨CPU有效并行化的工作,作为绕过全局解释器锁的一种方式.(我忽略了multiprocessing本讨论的分布式功能.)multiprocessing因此通常用于那些如果没有GIL,你会使用线程的情况.(注意,在这方面,multiprocessing模块的API 在模块之后紧密建模threading.)

对于帖子末尾的具体问题:(1)当父母被终止时,没有任何关于python的事情.如果父级在退出之前将其终止(或者整个进程组被终止),则只会终止Web服务器的子级.(2)你链接到的方法看起来像是在尝试复制守护进程而不知道标准习惯用法.有许多用于创建守护进程的包; 你应该使用其中一个.

  • 背景/前景的区别特定于外壳中的作业控制。通常,在应用程序中使用这些术语进行流程管理是没有意义的。在更一般的上下文中,守护进程是进程本身执行的操作,使用`subprocess.Popen`启动此类进程是完全标准的。python-daemon很好; 它具有繁琐的API,但是经过了实战测试,并且后者的质量很重要,因为很容易使这类错误弄错。 (2认同)