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.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)
当你看到
[INFO/MainProcess] calling join() for process p1
Run Code Online (Sandbox Code Playgroud)
这意味着主进程还没有退出——它正在关闭的过程中,但当然在join返回之前不会关闭......这只会在加入的进程完成后发生。
所以时间轴确实如你希望它是-但因为这join要p1的是最后认为,main过程永远不会,你没有看到,从它的输出或记录。(main 已经采取了所有终止触发的操作,但作为一个进程,它在此之前仍然存在)。
要进行验证,请ps在运行它时从另一个终端使用(在 Unixy 系统上)(可能会有稍长的延迟来帮助您检查):您永远不会看到一个 Python 进程从这个复杂的进程中运行 - 将有两个(主要和p1) 直到结束。