在守护程序线程中创建的进程的主线程是守护进程本身是一个Python错误吗?

时间:2015-06-25 16:34:49

标签: python multithreading multiprocessing fork

当我在守护程序线程中调用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实现中的错误吗?

2 个答案:

答案 0 :(得分:1)

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

请参阅此处的相关源代码:

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

所以在fork之后,只有一个线程,因此它就是主线程。

这意味着它永远不会成为守护程序线程。

我不能指出任何超出源代码的文档,但它肯定是而不是一个错误 - 如果你的期望得到满足,那将是另一回事。

fork和threads之间的交互是复杂的,正如我所提到的:不要在fork之前混合它们。

答案 1 :(得分:-1)

  

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

您明确等待线程结束。线程是否是守护程序对t.join()没有影响。除非子进程因os.waitpid()而终止,否则该线程将再次结束。

我不确定分叉线程的行为,所以我不能告诉你为什么你会经历你做的事情。