为什么在python中主进程退出时子进程(daemon=True)不退出?
以下是python多处理中为什么在python中主进程退出时子进程(daemon=True)不退出?,python,process,daemon,Python,Process,Daemon,以下是python多处理中守护进程标志的官方解释: 当进程退出时,它会尝试终止其所有daemonic子进程 据我所知,父进程将在退出时杀死其守护进程标志设置为True的子进程 下面是我用来证明我猜测的代码。但结果是不同的 import multiprocessing def child(): while True: pass for x in xrange(1, 4): proc = multiprocessing.Process(target=child
守护进程
标志的官方解释:
当进程退出时,它会尝试终止其所有daemonic子进程
据我所知,父进程将在退出时杀死其守护进程标志设置为True的子进程
下面是我用来证明我猜测的代码。但结果是不同的
import multiprocessing
def child():
while True:
pass
for x in xrange(1, 4):
proc = multiprocessing.Process(target=child, args=())
proc.daemon=True
proc.start()
while True:
pass
上面启动4个子进程和一个主进程。
我杀死了主进程,但4个孩子没有退出
既然守护进程被设置为true,为什么它们不被main终止呢?是的,您的理解是正确的,您的测试代码也可以 我刚刚添加了一些sleep语句来调试输出(如果没有
sleep
,很难从大量打印输出中推断):
现在,当我运行这个脚本时,当它运行时,我做了一个ps aux
,可以看到四个进程从这个脚本运行。7秒钟后,当我再次执行ps aux
时,我再也看不到这些进程正在运行-这意味着:
当主进程退出时,它终止了所有守护进程
之后,我还将proc.daemon
设置为False
,并再次运行脚本。这一次,即使在7秒钟之后,当我执行ps aux
时,我仍然可以看到子进程正在运行(因为它们现在是非守护进程,即使主进程终止,它们也不会退出)
因此,这是预期的工作-让我知道,如果你仍然有一个问题在这里
编辑1:
感谢@CristiFati指出最初的清理问题。
此代码之所以有效,是因为调用
sys.exit()
也会按照详细说明注册atexit
回调。注意:
- xrange的使用意味着Python 2
将产生3个值,而不是4个值(因此,只有3个子项)xrange(1,4)
#/usr/bin/env蟒蛇2
导入系统
导入多处理
导入操作系统
导入时间
print_text_pattern=“进程{0:s}的输出-pid:{1:d},ppid:{2:d}”
def子项(名称):
尽管如此:
打印(打印文本模式格式(名称,os.getpid(),os.getppid())
时间。睡眠(1)
def main():
procs=list()
对于x范围内的x(1,3):
proc_name=“Child{0:d}”。格式(x)
proc=multiprocessing.Process(target=child,args=(proc\u name,))
proc.daemon=True#x%2==0
打印(“进程{0:s}守护进程:{1:}”。格式(进程名称,进程守护进程))
过程追加(proc)
对于进程中的进程:
程序启动()
计数器=0
当计数器<3时:
打印(打印文本格式(“Main”、os.getpid()、os.getppid()))
时间。睡眠(1)
计数器+=1
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main()
打印(“\n完成”)
注释:
- 稍微改变了生成子进程的方式:首先创建所有子进程,然后才开始
- 添加了来自每个进程的一些打印调用,以跟踪它们在stdout中的活动-还添加了一些
调用(1秒),以避免产生太多的输出time.sleep
- 最重要的-主流程不再永远运行。在某个点上,它会优雅地退出(在3个循环之后——由于计数器变量),而我前面提到的行为也会在这个点上开始
这也可以通过截取术语信号(以及其他可以通过kill命令显式发送的信号)并执行清理来实现——这样在杀死主进程时也会杀死子进程——但这更复杂 - 我把事情简化了一点,只生了两个孩子
- 移动了包含在
中的名称条件,因此如果导入中的主函数(用于结构)中的所有内容(如果
proc.daemon
,然后监视输出和ps-ef | grep“code00.py”
输出[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]>python2代码00.py
Python 2.7.12(默认值,2019年10月8日,14:14:10)[GCC 5.4.0 20160609]linux2上的64位
进程Child1守护进程:True
进程Child2守护进程:True
工艺主管道的输出-pid:1433,ppid:1209
来自进程Child1的输出-pid:1434,ppid:1433
来自过程Child2的输出-pid:1435,ppid:1433
工艺主管道的输出-pid:1433,ppid:1209
来自过程Child2的输出-pid:1435,ppid:1433
来自进程Child1的输出-pid:1434,ppid:1433
工艺主管道的输出-pid:1433,ppid:1209
来自进程Child1的输出-pid:1434,ppid:1433
来自过程Child2的输出-pid:1435,ppid:1433
来自进程Child1的输出-pid:1434,ppid:1433
来自过程Child2的输出-pid:1435,ppid:1433
完成。
你在哪个操作系统上?当我试着打开窗户时
import multiprocessing
import time
import sys
print("main")
def child():
while True:
print("child")
time.sleep(3)
for x in xrange(1, 4):
proc = multiprocessing.Process(target=child, args=())
proc.daemon=True
proc.start()
time.sleep(7)
print("exit")
sys.exit() # this exits the main process