我正在学习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'我得到的输出是:
main starting
p1 Starting
p2 Starting
main exiting
p1 Exiting预期产出:
main starting
p1 Starting
p2 Starting
main exiting
p2 Exiting
p1 Exiting经过几次搜索,我找到了this answer,并将下面的一行插入到我的代码中。
logger = multiprocessing.log_to_stderr(logging.INFO)我得到的输出是,
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根据我的理解,
但是在这里,为什么主要进程试图在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发布于 2015-02-20 05:13:10
当你看到
[INFO/MainProcess] calling join() for process p1这意味着主进程还没有退出--在中--关闭的进程,但是在join返回之前当然不会关闭.只有在连接过程完成后才会发生这种情况。
所以时间线确实和你所期望的一样--但是由于join to p1是最后一次想到main进程做过的事情,所以在输出或日志记录中看不到这一点。(main已经采取了所有由终止触发的操作,但作为一个过程,它在此之前仍然存在。)
要验证,请(在Unixy系统上)在运行这个终端时使用来自另一个终端的ps (可能会有稍长的延迟来帮助您检查):您将不会看到一个单独的process从这个复杂的部分中运行出来--在结束之前将有两个(main和p1)。
发布于 2020-12-10 13:23:21
Python多进程\ Daemon & Join
问题最后增加了更多等待守护进程标志和联接方法的行为,因此这里用一个简单的脚本进行了快速解释。
输入
import multiprocessing
import time
import logging
def daemon():
p = multiprocessing.current_process()
print('Starting:', p.name, p.pid, flush=True)
print('---' * 15)
time.sleep(2)
print('===' * 15 + ' < ' + f'Exiting={p.name, p.pid}' + ' > ' + '===' * 15, flush=True)
def non_daemon():
p = multiprocessing.current_process()
print('Starting:', p.name, p.pid, flush=True)
print('---'*15)
print('===' * 15 + ' < ' + f'Exiting={p.name, p.pid}' + ' > ' + '===' * 15, flush=True)
if __name__ == '__main__':
print('==='*15 + ' < ' + 'MAIN PROCESS' + ' > ' + '==='*15)
logger = multiprocessing.log_to_stderr(logging.INFO)
# DAEMON
daemon_proc = multiprocessing.Process(name='MyDaemon', target=daemon)
daemon_proc.daemon = True
# NO-DAEMON
normal_proc = multiprocessing.Process(name='non-daemon', target=non_daemon)
normal_proc.daemon = False
daemon_proc.start()
time.sleep(2)
normal_proc.start()
# daemon_proc.join()输出无连接法
============================================= < MAIN PROCESS > =============================================
Starting: MyDaemon 8448
---------------------------------------------
[INFO/MyDaemon] child process calling self.run()
[INFO/MainProcess] process shutting down
[INFO/MainProcess] calling terminate() for daemon MyDaemon
[INFO/MainProcess] calling join() for process MyDaemon
[INFO/MainProcess] calling join() for process non-daemon
Starting: non-daemon 6688
---------------------------------------------
============================================= < Exiting=('non-daemon', 6688) > =============================================
[INFO/non-daemon] child process calling self.run()
[INFO/non-daemon] process shutting down
[INFO/non-daemon] process exiting with exitcode 0
Process finished with exit code 0函数daemon()是'spleeping‘2秒,因此当Python到达脚本底部时,程序就关闭了,而不是daemon()。
[INFO/MainProcess] calling terminate() for daemon MyDaemon
现在,如果没有注释脚本的最后一行,daemon_proc.join()。
输出+连接法
============================================= < MAIN PROCESS > =============================================
Starting: MyDaemon 13588
---------------------------------------------
[INFO/MyDaemon] child process calling self.run()
============================================= < Exiting=('MyDaemon', 13588) > =============================================
[INFO/MyDaemon] process shutting down
[INFO/MyDaemon] process exiting with exitcode 0
[INFO/MainProcess] process shutting down
[INFO/MainProcess] calling join() for process non-daemon
Starting: non-daemon 13608
---------------------------------------------
============================================= < Exiting=('non-daemon', 13608) > =============================================
[INFO/non-daemon] child process calling self.run()
[INFO/non-daemon] process shutting down
[INFO/non-daemon] process exiting with exitcode 0
Process finished with exit code 0https://stackoverflow.com/questions/28621872
复制相似问题