2015-06-25 180 views
2

当我打电话os.fork()守护线程内,在子进程的主线程有daemon属性设置为True。这非常令人困惑,因为程序保持运行,而唯一的线程是守护进程。根据文档,如果所有的线程都是守护进程,程序应该退出。在守护进程线程中创建的进程的主线程是守护进程本身吗?

下面是一个例子:

import os 
import threading 


def child(): 
    assert not threading.current_thread().daemon # This shouldn't fail 


def parent(): 
    new_pid = os.fork() 
    if new_pid == 0: 
     child() 
    else: 
     os.waitpid(new_pid, 0) 


t = threading.Thread(target=parent) 
t.setDaemon(True) 
t.start() 
t.join() 

是它的CPython的实现中的错误?

+0

我是否正确地纠正你的问题? –

+0

是的,谢谢! –

回答

-1

这非常令人困惑,因为程序保持运行,而唯一的线程是守护进程。根据文档,如果所有的线程都是守护进程,程序应该退出。

你被明确等待线程结束。线程是否为守护进程对t.join()没有影响。除非子进程已由于os.waitpid()而终止,否则该线程将不会结束。

我不知道有关分叉线程的行为,虽然如此,我不能告诉你为什么你遇到你做什么。

+0

来自downvoter的评论会很好。 –

+0

问题是关于子进程主线程的守护进程状态,而不是关于父进程。 –

0

此行为的原因是,守护进程只与线程其他比主线程相关。在主线程中,current_thread().daemon的返回值被硬编码为False

请参阅相关的源代码在这里:

https://github.com/python/cpython/blob/2.7/Lib/threading.py#L1097

所以叉后,只有一个线程,它是因此主线程。

这意味着它可以永远是一个守护线程。

我无法指出任何超出源代码的文档,但它肯定是而不是的一个错误 - 如果您的期望得到满足,它将成为一个错误。

叉和线程之间的相互作用是复杂的,正如我所说:不叉前混合。

+0

你能指出官方的Python文档,它说这是预期的行为吗?国际海事组织的文件很清楚:如果所有的线程都是守护进程,则进程终止。这根本不会发生。 –