0

我有一個Python編程的問題。我在寫一個有線程的代碼。此線程是被阻止的線程。被阻塞的線程意味着:線程正在等待事件。如果事件未設置,則此線程必須等待,直到事件被設置。我期望block線程必須等待事件,而不需要等待超時!
開始阻塞的線程後,我寫了一個永久循環來計算一個計數器。問題是:當我想通過Ctrl + C終止我的Python程序時,我無法正確終止阻塞的線程。這個線程還活着!我的代碼在這裏。Python阻塞的線程終止方法?

import threading 
import time 

def wait_for_event(e): 
    while True: 
     """Wait for the event to be set before doing anything""" 
     e.wait() 
     e.clear() 
     print "In wait_for_event" 

e = threading.Event() 
t1 = threading.Thread(name='block', 
         target=wait_for_event, 
         args=(e,)) 
t1.start() 

# Check t1 thread is alive or not 
print "Before while True. t1 is alive: %s" % t1.is_alive() 

counter = 0 
while True: 
    try: 
     time.sleep(1) 
     counter = counter + 1 
     print "counter: %d " % counter 
    except KeyboardInterrupt: 
     print "In KeyboardInterrupt branch" 
     break 

print "Out of while True" 
# Check t1 thread is alive 
print "After while True. t1 is alive: %s" % t1.is_alive() 

輸出:

$ python thread_test1.py 
Before while True. t1 is alive: True 
counter: 1 
counter: 2 
counter: 3 
^CIn KeyboardInterrupt branch 
Out of while True 
After while True. t1 is alive: True 

誰能給我幫助嗎?我想問2個問題。
1.我可以通過Ctrl + C停止阻塞的線程嗎?如果可以的話,請給我一個可行的方向。
2.如果我們通過Ctrl + \鍵盤停止Python程序或重置運行Python程序的硬件(例如PC),被阻塞的線程可以被終止或不被終止?

回答

1

按Ctrl + C停止僅主線程,你的線程不在daemon模式,這就是爲什麼他們保持運行,這就是保持過程活着。首先讓你的線程進入守護進程。

t1 = threading.Thread(name='block', 
         target=wait_for_event, 
         args=(e,)) 
t1.daemon = True 
t1.start() 

類似地爲您的其他線程。但是還有另外一個問題 - 一旦主線程啓動了你的線程,就沒有別的辦法了。所以它退出,線程立即被破壞。所以,讓我們保持主線程活着:

import time 
while True: 
    time.sleep(1) 

this看看,我希望你能得到你的答案。

+0

我能問你2個問題嗎?我沒有線程終止的經驗。我會在這裏問第一個問題,因爲這仍然讓我不清楚。在第一個問題中,我暫時忽略了「讓主線保持活躍」的情況。如果我們將t1線程設置爲'daemon',那麼當我們按下Ctrl + C時它還是活着嗎?我把t1線程作爲'daemon',但我仍然看到'After while True。當我按Ctrl + C時,t1是活着的:True'。這意味着即使主程序可以退出,但t1線程仍在運行!它是否正確? – jackbk

+0

是的,它是正確的...通過將它們設置爲守護進程線程,您可以讓它們運行並忘記它們,並且當程序退出時,任何守護進程線程都會自動終止。 –

+0

謝謝。我瞭解你對守護線程的解釋。我的第二個問題是你對主線程的評論:「一旦主線程啓動你的線程,就沒有其他任何事情要做」,「那麼讓我們保持主線程活着」。你的意思是我不應該有'KeyboardInterrupt'異常?我爲'KeyboardInterrupt'使用異常,因爲如果用戶按下Ctrl + C,我的python程序必須退出。這是我的意圖。 – jackbk

1

如果你需要殺死所有正在運行的python進程,你可以簡單地從命令行運行pkill python。 這是有點極端,但會工作。

另一個解決辦法是使用你的代碼中看到鎖定here

+0

謝謝。我認爲我們不應該按Ctrl + C或Ctrl + \來殺死一個程序。停止python程序並不是一個好方法。但是我真的好奇線程運行,如果我們通過Ctrl + C或Ctrl + \殺死python程序。所以我在這個主題中問了這個問題。關於「鎖定」,我已閱讀到目前爲止,但我不熟悉這種方法。我熟悉SystemC中的「事件等待」,所以我在Python中嘗試了相同的方法(事件等待)。這是在我的例子中通過「事件等待」使用阻塞線程的原因。 – jackbk