Python 多处理守护进程 vs 非守护进程 vs 主进程

Rat*_*Don 5 python multiprocessing

我正在 Python 中学习多处理,同时我发现守护进程和非守护进程之间关于主进程的这种奇怪行为。 我的代码:

import multiprocessing
import time

def worker(name,num):
    print name, 'Starting'
    time.sleep(num)
    print name, 'Exiting'

if __name__ == '__main__':
    print 'main starting'
    p1=multiprocessing.Process(target=worker, args=("p1",7,))
    p2=multiprocessing.Process(target=worker, args=("p2",5,))
    p2.daemon=True
    p1.start()
    p2.start()
    time.sleep(4)
    print 'main exiting'
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

main starting
p1 Starting
p2 Starting
main exiting
p1 Exiting
Run Code Online (Sandbox Code Playgroud)

预期输出:

main starting
p1 Starting
p2 Starting
main exiting
p2 Exiting
p1 Exiting
Run Code Online (Sandbox Code Playgroud)

经过几次搜索,我找到了这个答案并将以下行插入到我的代码中。

logger = multiprocessing.log_to_stderr(logging.INFO)
Run Code Online (Sandbox Code Playgroud)

我得到的输出是,

main starting
[INFO/p1] child process calling self.run()
p1 Starting
[INFO/p2] child process calling self.run()
p2 Starting
main exiting
[INFO/MainProcess] process shutting down
[INFO/MainProcess] calling terminate() for daemon p2
[INFO/MainProcess] calling join() for process p2
[INFO/MainProcess] calling join() for process p1
p1 Exiting
[INFO/p1] process shutting down
[INFO/p1] process exiting with exitcode 0
Run Code Online (Sandbox Code Playgroud)

按照我的理解,

  • 当主进程退出时,它会终止其所有子守护进程。(可以在这里看到)
  • 主进程不能在其所有子非守护进程退出之前退出。

但是在这里,为什么主进程试图在 p1 退出之前关闭?

  • p1 启动并休眠 7 秒。
  • p2 启动并休眠 5 秒。
  • 主进程休眠 4 秒。
  • 主进程在 4 秒后唤醒并等待 p1 退出。
  • p2 5 秒后唤醒并退出。
  • p1 7 秒后唤醒并退出。
  • 主进程退出。

以上不是上述程序的正常时间表吗?

谁能解释一下这里发生了什么以及为什么?

编辑

在p1.join()代码末尾添加行后,我得到以下输出:

main starting
[INFO/Process-1] child process calling self.run()
p1 Starting
[INFO/Process-2] child process calling self.run()
p2 Starting
main exiting
p2 Exiting
[INFO/Process-2] process shutting down
[INFO/Process-2] process exiting with exitcode 0
p1 Exiting
[INFO/Process-1] process shutting down
[INFO/Process-1] process exiting with exitcode 0
[INFO/MainProcess] process shutting down
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 5

当你看到

[INFO/MainProcess] calling join() for process p1
Run Code Online (Sandbox Code Playgroud)

这意味着主进程还没有退出——它正在关闭的过程中,但当然在join返回之前不会关闭......这只会在加入的进程完成后发生。

所以时间轴确实如你希望它是-但因为这join要p1的是最后认为,main过程永远不会,你没有看到,从它的输出或记录。(main 已经采取了所有终止触发的操作,但作为一个进程,它在此之前仍然存在)。

要进行验证,请ps在运行它时从另一个终端使用(在 Unixy 系统上)(可能会有稍长的延迟来帮助您检查):您永远不会看到一个 Python 进程从这个复杂的进程中运行 - 将有两个(主要和p1) 直到结束。

  • 主进程强行终止守护进程作为其关闭活动的一部分(在等待 p1 之前,这是它所做的最后一件事——多处理的规范不会强制顺序是这种方式,但他们也不会在任何情况下禁止它方式、形状或形式);p2 是守护进程;因此,p2 被强行终止。不知道您为什么期望其他方式,但是,无论您期望什么,它都不会遵循规范,并且(不违反规范)它不会发生。 (2认同)