Pyr*_*rce 12 python multiprocessing
我有一个Python 2.7多处理过程,它不会在父进程退出时退出.我设置了守护进程标志,它应该强制它在父母死亡时退出.文档指出:
"当一个进程退出时,它会尝试终止所有守护进程的子进程."
p = Process(target=_serverLaunchHelper, args=args)
p.daemon = True
print p.daemon # prints True
p.start()
Run Code Online (Sandbox Code Playgroud)
当我通过kill命令终止父进程时,守护进程处于活动状态并且正在运行(在下次运行时阻塞该端口).子进程正在启动SimpleHttpServer并在serve_forever不执行任何其他操作的情况下进行调用.我的猜测是文档中的"尝试"部分意味着阻塞服务器进程正在停止进程死亡,并且它会让进程因此而变为孤立状态.我可以让孩子将服务推送到另一个Thread并让主线程检查父进程id的更改,但这似乎只是复制守护进程功能的很多代码.
是否有人能够深入了解守护程序标志无法正常工作的原因?这在windows8 64位和ubuntu12 32位vm上是可重复的.
流程函数的简化版本如下:
def _serverLaunchHelper(port)
httpd = SocketServer.TCPServer(("", port), Handler)
httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)
aba*_*ert 10
当进程退出时,它会尝试终止其所有守护进程子进程.
这里的关键词是"尝试".另外,"退出".
根据您的平台和实现,可能是终止守护进程子进程的唯一方法是明确地这样做.如果父进程正常退出,它有机会明确地这样做,所以一切都很好.但是如果父进程突然终止,它就不会.
对于CPython的特别,如果你看看源,终止恶魔的过程中的处理方式为加入非恶魔的过程相同:通过走active_children()在atexit函数.因此,当且仅当您的atexit处理程序运行时,您的守护程序才会被杀死.并且,正如该模块的文档所说:
注意:当程序被Python未处理的信号杀死,检测到Python致命内部错误或被调用时,不会调用通过此模块注册的函数
os._exit().
根据您如何杀死父级,您可以通过添加信号处理程序来拦截突然终止来解决此问题.但是你可能不会 - 例如,在POSIX上,SIGKILL不能拦截,所以如果你kill -9 $PARENTPID,这不是一个选择.
另一种选择是杀死进程组,而不仅仅是父进程.例如,如果你的父母有PID 12345,那么kill -- -12345在Linux上将杀死它及其所有孩子(假设你没有做任何花哨的事情).