注意事项:
-
xrange的使用暗示Python 2
-
xrange(1, 4) 将产生 3 个值而不是 4 个(因此,只有 3 个孩子)
事情并非如此。文档 ([Python 2.Docs]: multiprocessing - daemon) 可能应该更具体。
问题是 multiprocessing 注册了一个 cleanup 函数 以在退出时杀死其所有 deamonic 子级。这是通过[Python 2.Docs]: atexit - Exit handlers 完成的:
注意:当程序被 Python 未处理的信号杀死、检测到 Python 致命内部错误或调用 os._exit() 时,不会调用通过此模块注册的函数.
您不处理 TERM 信号(默认由 kill 命令发送),因此主进程不会调用清理函数(保留其子进程)运行)。
我修改了您的代码以更好地说明行为。
code00.py:
#!/usr/bin/env python2
import sys
import multiprocessing
import os
import time
print_text_pattern = "Output from process {0:s} - pid: {1:d}, ppid: {2:d}"
def child(name):
while True:
print(print_text_pattern.format(name, os.getpid(), os.getppid()))
time.sleep(1)
def main():
procs = list()
for x in xrange(1, 3):
proc_name = "Child{0:d}".format(x)
proc = multiprocessing.Process(target=child, args=(proc_name,))
proc.daemon = True #x % 2 == 0
print("Process {0:s} daemon: {1:}".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 {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main()
print("\nDone.")
注意事项:
- 稍微改变了子进程的生成方式:所有子进程都是在 1st 创建的,然后才开始
- 添加了来自每个进程的一些 print 调用,以跟踪它们在 stdout 中的活动 - 还添加了一些
time.sleep 调用(1 秒),以避免产生过多输出
-
最重要的 - 主进程不再永远运行。在某些时候,它会优雅地退出(在 3 个周期后 - 由于 counter 变量),并且我之前提到的行为会出现。
这也可以通过拦截 TERM 信号(以及其他可以通过 kill 命令显式发送的信号)并执行清理 - 这样子进程也会在杀死主进程时被杀死 -但这更复杂
- 我稍微简化了一下,只生成了 2 个孩子
- 移动了 main 函数(用于结构)中的所有内容,该函数包含在
if __name__ == "__main__": 条件中,因此如果您导入模块 ,则不会生成进程
- 为每个孩子指定不同的值
proc.daemon,然后监控输出和ps -ef | grep "code00.py" 输出
- 为 child func 添加了一个参数 (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] 64bit 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.