当我在守护程序线程中调用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 :(得分: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()
而终止,否则该线程将再次结束。
我不确定分叉线程的行为,所以我不能告诉你为什么你会经历你做的事情。