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终端会话中.
当我退出终端(使用exit
或CTRL+ 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)你链接到的方法看起来像是在尝试复制守护进程而不知道标准习惯用法.有许多用于创建守护进程的包; 你应该使用其中一个.