You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中设置daemon=True的子进程为何在主进程退出时不终止?

Python Multiprocessing Daemon 进程未被终止的问题分析

我懂你的困惑——官方文档明确说父进程退出时会尝试终止所有守护子进程,但你自己写的测试代码却没得到预期结果,对吧?咱们先把你的代码补全,再一步步拆解问题出在哪。

首先,先把你的测试代码补全(我猜你是漏写了proc.start(),而且可能没加Windows下必须的入口保护):

import multiprocessing
import time

def child():
    while True:
        print(f"子进程 {multiprocessing.current_process().pid} 运行中...")
        time.sleep(1)

if __name__ == "__main__":
    for x in range(1, 4):
        proc = multiprocessing.Process(target=child, args=())
        proc.daemon = True
        proc.start()
    
    print("父进程即将退出")
    time.sleep(2)

接下来,咱们分析可能导致你结果不符的几个常见原因:

  • 缺少if __name__ == "__main__":保护:在Windows系统下,multiprocessing模块通过创建新进程重新导入脚本的方式启动子进程,如果没有这个入口保护,子进程会重复执行整个脚本,导致额外的进程被创建,让你误以为原来的守护进程没被终止。这是Windows下使用multiprocessing的必加项。

  • 父进程未正常退出:官方文档里的“尝试终止”是建立在父进程正常退出的基础上的。如果父进程是被强制杀死的(比如Unix下用kill -9,Windows下强制结束任务),它根本没机会向守护子进程发送终止信号,这些子进程会变成孤儿进程,被系统的init/systemd进程接管,继续运行。

  • 没给父进程足够的终止时间:父进程退出时,需要一点时间来给守护子进程发送终止信号并等待它们结束。如果你在父进程刚退出就立刻查看进程状态,可能会看到子进程还没来得及被终止,过几秒再查就会发现它们已经消失了。

再回头看官方文档的描述:

当一个进程退出时,它会尝试终止所有守护子进程。

这里的“尝试”是关键:父进程会向守护子进程发送终止信号(Unix是SIGTERM,Windows是TerminateProcess),对于像你的死循环这种没有阻塞系统调用的子进程,会很快响应信号并终止;但如果子进程卡在无法被中断的系统调用里,可能需要额外处理,但这种情况比较少见。

你可以运行上面补全后的代码试试:父进程等待2秒后退出,子进程的打印会立刻停止,用进程管理工具查看的话,那些守护子进程也会跟着父进程一起消失。

内容的提问来源于stack exchange,提问作者Kramer Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:26:57