2011-07-06 33 views
6

我正在Windows上編寫一個多線程的Python應用程序。使用線程時Ctrl-C不起作用。計時器

我曾經使用ctrl-c來終止應用程序,但是一旦我添加threading.Timer實例ctrl-c停止工作(或者有時需要很長時間)。

這怎麼可能?
有定時器線程和ctrl-c之間的關係是什麼?

UPDATE:
我發現Python的thread documentation如下:一個KeyboardInterrupt 異常將通過 任意線程接收:

線程與 中斷奇怪的交互。 (當信號 模塊可用,總是中斷 去主線程。)

+0

是否有可能將代碼粘貼到此處? – Rahul

回答

4

的方式threading.Thread(因此threading.Timer)工作原理是,每個線程自己註冊到threading模塊,並在解釋退出解釋器將等待所有已註冊的線程退出,然後終止解釋器。這樣做是爲了讓線程實際上完成執行,而不是讓解釋器在其下面被粗暴地移除。所以當你點擊^ C時,主線程收到信號,決定終止並等待定時器結束。

您可以設置線程(與setDaemon方法)使線程模塊不是等待這些線程,但如果他們碰巧被執行Python代碼,而解釋退出,你退出的過程會比較混亂的錯誤。即使您取消threading.Timer(並將其設置爲守護進程),它仍然可以在解釋器被銷燬時喚醒 - 因爲threading.Timercancel方法只是告知threading.Timer它在喚醒時不執行任何操作,但它必須實際執行Python代碼來做出決定。

沒有優雅的方式來終止線程(除了當前的線程),也沒有可靠的方法來中斷被阻塞的線程。定時器更易於管理的方法通常是事件循環,就像GUI和其他事件驅動系統爲您提供的那樣。使用什麼完全取決於你的程序會做什麼

+0

謝謝你的觀點。暫時我標記了解決問題的線程守護進程,但是我想在某些時候我必須重構纔能有適當的終止流程。 – Jonathan

+0

如果定時器設置在同一個線程中,信號處理程序是否會執行?如果是這樣,如果一個timer.Cancel可以在信號處理程序中設置,現在該進程可以退出嗎? – Vivek

+0

+1。有沒有解釋爲什麼有一些資源*「沒有優雅的方式來終止線程(除了當前的線程),並且沒有可靠的方法來中斷被阻塞的線程」*? – n611x007

2

David Beazley介紹了這個話題。該PDF可用here。瀏覽第22--25頁(「插曲:信號」到「凍結信號」)。

+0

這真的是一個有洞察力的PDF! – Jonathan