注意:
事实并非如此。文档([Python 2.Docs]: multiprocessing - daemon)可能需要更具体的说明。
问题在于,当退出时,multiprocessing会注册一个清理函数来终止所有守护进程子项。这是通过[Python 2.Docs]: atexit - Exit handlers完成的(强调是我的):
注意:通过此模块注册的函数在程序被Python未处理的信号杀死、检测到Python致命内部错误或调用
os._exit()时不会被调用。
您没有处理
TERM信号(默认由
kill命令发送),因此清理函数不会被主进程调用(导致其子进程继续运行)。
我修改了您的代码以更好地说明这种行为。
code00.py:
import multiprocessing
import os
import sys
import time
print_text_pattern = "Output from process {:s} - pid: {:d}, ppid: {:d}"
def child(name):
while True:
print(print_text_pattern.format(name, os.getpid(), os.getppid()))
time.sleep(1)
def main(*argv):
procs = list()
for x in xrange(1, 3):
proc_name = "Child{:d}".format(x)
proc = multiprocessing.Process(target=child, args=(proc_name,))
proc.daemon = True
print("Process {:s} daemon: {:}".format(proc_name, proc.daemon))
procs.append(proc)
for proc in procs:
proc.start()
counter = 0
while counter < 3:
print(print_text_pattern.format("Main", os.getpid(), os.getppid()))
time.sleep(1)
counter += 1
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.\n")
sys.exit(rc)
笔记:
稍微改变了子进程的生成方式:所有子进程都是在第一次创建后才开始运行。
为每个进程添加了一些打印调用,以跟踪它们在标准输出中的活动 - 还添加了一些时间延迟调用(1秒),以避免产生过多的输出。
最重要的是 - 主进程不再永远运行。在某个时刻,它会优雅地退出(经过3个循环 - 根据计数器变量),然后就会出现我之前提到的行为。
这也可以通过拦截TERM信号(和其他可以由kill命令显式发送的信号)并进行清理来实现 - 这样当杀死主进程时,子进程也会被杀死 - 但这更加复杂。
我简化了一些东西,只生成了2个子进程。
将所有内容移动到一个main函数中(为了结构),并放在一个if __name__ == "__main__":
条件语句中,这样如果你导入该模块,就不会生成进程。
为每个子进程的proc.daemon赋予不同的值,然后监视输出和ps -ef | grep "code00.py"
输出。
为child函数添加了一个参数(name),但这只是为了显示目的。
输出:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> python2 ./code00.py
Python 2.7.12 (default, Oct 8 2019, 14:14:10) [GCC 5.4.0 20160609] 064bit on linux2
Process Child1 daemon: True
Process Child2 daemon: True
Output from process Main - pid: 1433, ppid: 1209
Output from process Child1 - pid: 1434, ppid: 1433
Output from process Child2 - pid: 1435, ppid: 1433
Output from process Main - pid: 1433, ppid: 1209
Output from process Child2 - pid: 1435, ppid: 1433
Output from process Child1 - pid: 1434, ppid: 1433
Output from process Main - pid: 1433, ppid: 1209
Output from process Child1 - pid: 1434, ppid: 1433
Output from process Child2 - pid: 1435, ppid: 1433
Output from process Child1 - pid: 1434, ppid: 1433
Output from process Child2 - pid: 1435, ppid: 1433
Done.