首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python多处理守护进程vs非守护进程与main

Python多处理守护进程vs非守护进程与main
EN

Stack Overflow用户
提问于 2015-02-20 04:56:11
回答 2查看 5.7K关注 0票数 6

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

代码语言:javascript
复制
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'

我得到的输出是:

代码语言:javascript
复制
main starting
p1 Starting
p2 Starting
main exiting
p1 Exiting

预期产出:

代码语言:javascript
复制
main starting
p1 Starting
p2 Starting
main exiting
p2 Exiting
p1 Exiting

经过几次搜索,我找到了this answer,并将下面的一行插入到我的代码中。

代码语言:javascript
复制
logger = multiprocessing.log_to_stderr(logging.INFO)

我得到的输出是,

代码语言:javascript
复制
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开始睡觉7秒。
  • p2启动并睡觉5秒。
  • 主进程休眠4秒。
  • 主进程在4秒后醒来,并等待p1退出。
  • p2在5秒后醒来,然后退出。
  • p1在7秒后醒来,然后退出。
  • 主进程退出。

会不会是上述节目的正常时间线?

有人能解释一下这里发生了什么吗?为什么?

编辑

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

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-20 05:13:10

当你看到

代码语言:javascript
复制
[INFO/MainProcess] calling join() for process p1

这意味着主进程还没有退出--在中--关闭的进程,但是在join返回之前当然不会关闭.只有在连接过程完成后才会发生这种情况。

所以时间线确实和你所期望的一样--但是由于join to p1是最后一次想到main进程做过的事情,所以在输出或日志记录中看不到这一点。(main已经采取了所有由终止触发的操作,但作为一个过程,它在此之前仍然存在。)

要验证,请(在Unixy系统上)在运行这个终端时使用来自另一个终端的ps (可能会有稍长的延迟来帮助您检查):您将不会看到一个单独的process从这个复杂的部分中运行出来--在结束之前将有两个(main和p1)。

票数 5
EN

Stack Overflow用户

发布于 2020-12-10 13:23:21

Python多进程\ Daemon & Join

问题最后增加了更多等待守护进程标志和联接方法的行为,因此这里用一个简单的脚本进行了快速解释。

  1. 守护进程在主程序退出之前自动终止,以避免使孤立的进程继续运行,但不会随着主程序而终止。因此,任何由守护函数遗留的未执行进程都不会运行!
  2. 但是,如果在守护函数上调用了join()方法,那么主程序将等待剩余的进程.

输入

代码语言:javascript
复制
        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()

输出无连接法

代码语言:javascript
复制
============================================= < 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()

输出+连接法

代码语言:javascript
复制
============================================= < 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 0
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28621872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档