2017-09-21 116 views
1

我運行下面的代碼:Time.sleep似乎阻止主線程,而不僅僅是子線程?

from threading import Thread 
from time import sleep 

def file_write(file_input, num_lines): 
    sleep(10) 
    file = open("testfile.txt", "w") 
    for line in num_lines: 
     file.write("{}: {}".format(line, file_input)) 

    file.close() 


if __name__ == '__main__': 
    curr_thread = Thread(target=file_write, args=("Norah", range(5))) 
    curr_thread.daemon = False 
    curr_thread.start() 

的期望是主線程將立即退出,因爲我不叫加入。但事實並非如此。睡眠呼叫是否阻止主線程?

編輯:有在這個線程中提問的類似問題:time.sleep -- sleeps thread or process?但它是不一樣的。
我看了一下線程:它表示睡眠不會導致子進程阻塞對方,但它不會說主線程會發生什麼情況。當我從接受的答案中運行代碼時,主線程並沒有立即退出,就像我想的那樣。

更新:看起來像多線程不會解決我的問題:目標是在後臺運行一堆任務。我現在正在使用子流程模塊。

+0

可能重複的[time.sleep - 睡眠線程或進程?](https://stackoverflow.com/questions/92928/time-sleep-sleeps-thread-or-process) –

+0

我看着線程:它說睡眠不會導致子進程阻塞對方,但它並不會說主線程會發生什麼情況。當我從接受的答案中運行代碼時,主線程並沒有立即退出,就像我想的那樣。 –

+0

你在做'curr_thread.join()'嗎?主線程應該立即退出。加入線程將等到線程完成後退出。 –

回答

1

睡眠僅限緊急呼叫阻止他們是所謂的線程。在致電curr_thread.start()後立即在主線中打印任何內容將證明這一點。然而,如果你中斷了你的代碼(Ctrl-C),你會看到一個有用的堆棧跟蹤。最後一次調用是在threading模塊的_shutdown()方法中,該方法似乎在等待所有非守護進程線程完成。

t = _pickSomeNonDaemonThread() 
while t: 
    t.join() 
    t = _pickSomeNonDaemonThread() 

而且閱讀the documentation的線程模塊,你可以看到:「若沒有活着的非守護線程留給整個Python程序退出」所以,因爲你已經完成了curr_thread.daemon = False,你迫使主線程先等待這個線程完成。

但是我應該指出,線程繼承了父母的「守護進程」。由於主線程永遠不是守護進程線程,因此您可能已經離開了curr_thread.daemon = False,並且會得到相同的行爲。

+0

事情是,如果我設置了curr_thread.daemon = True,那麼程序立即退出,但子進程似乎在進程中被拆除:文件寫入調用不執行。 –

+0

@NorahBorus是的,第二個線程將被終止。這是因爲整個進程退出,因爲沒有非守護進程線程。主線程是唯一的非守護線程,如果你設置'curr_thread.daemon = True',對吧?所以當它結束時(立即,因爲你從不'join()'),整個過程將會退出。 – bnaecker

+0

@NorahBorus這看起來有點像XY問題。爲什麼你想創建第二個線程呢?或者這是一個瞭解線程模塊的練習嗎? – bnaecker

0

當然,線程中的睡眠不會阻塞主線程。

此代碼演示了主繼續說:

from threading import Thread 
from time import sleep 

def file_write(file_input, num_lines): 
    print('a') 
    sleep(5) 
    print('b') 


if __name__ == '__main__': 
    curr_thread = Thread(target=file_write, args=("Norah", range(5))) 
    curr_thread.daemon = False 
    curr_thread.start() 
    for i in range(5): 
     sleep(1) 
     print(i) 

輸出:

a 
0 
1 
2 
3 
b 
4 
+0

請參閱bnaeckner的評論和我的代碼示例:我指出問題是關於主線程退出時會發生什麼。 –