2015-06-25 228 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文檔,它說這是預期的行爲嗎?國際海事組織的文件很清楚:如果所有的線程都是守護進程,則進程終止。這根本不會發生。 –