2011-07-06 76 views
8

KeyboardInterrupts閒置工作對我來說90%的時間,但我想知道他們爲什麼不總是工作。在怠速時,如果我做Python空閒和KeyboardInterrupts

import time 
time.sleep(10) 

,然後用Ctrl + C嘗試一個KeyboardInterrupt,它不打斷這個過程,直到沉睡了10秒後。

相同的代碼和通過Ctrl + C的KeyboardInterrupt立即在shell中工作。

+0

哪個版本的Python?哪個平臺和操作系統? –

+0

Windows XP上的Python 2.7。謝謝。 – cssndrx

+0

在我的linux系統上,我發現當CTRL + C不起作用時,輸入終端命令'kill -2 '將停止空閒。 – JB0x2D1

回答

6

在IDLE源快速瀏覽揭示KeyboardInterrupts有一些特殊的情況下處理:http://svn.python.org/view/python/tags/r267/Lib/idlelib/PyShell.py?annotate=88851

最重要的是,代碼實際上是在一個單獨的方法,該方法的主要IDLE GUI程序經由通信RPC執行。你會是下模型來獲得不同的行爲 - 這是最好的只是規範的翻譯測試(通過命令行,互動等)

============

深入挖掘...

RPC服務器上的套接字在輔助線程中進行管理,該線程假定使用對thread.interrupt_main()(http://svn.python.org/view/python/tags/r267/Lib/idlelib/run.py?annotate=88851)的調用傳播KeyboardInterrupt。行爲並不像預期的那樣...本帖子提示,由於某些原因,interrupt_main不提供您期望的粒度級別:http://bytes.com/topic/python/answers/38386-thread-interrupt_main-doesnt-seem-work

cPython中的異步API函數有點愚蠢(根據我的經驗)由於解釋器循環是如何處理的,所以它不會讓我感到驚訝。 interrupt_main()調用PyErr_SetInterrupt()異步通知解釋器處理主線程中的SIGINT。從http://docs.python.org/c-api/exceptions.html#PyErr_SetInterrupt

此功能模擬到達一個SIGINT信號的 的效果 - 在未來 時間PyErr_CheckSignals()被調用時, 一個KeyboardInterrupt將提高

這需要解釋去,雖然再次調用PyErr_CheckSignals()之前的任意數量的字節碼指令 - 在time.sleep()期間可能不會發生。我冒昧地說,這是一個模擬SIGINT而不是實際發信號通知SIGINT的瑕疵。

+0

+1「用標準解釋器測試」。特別是在處理Idle時,它有一個真正的傾向,有很多魔法行爲。我向任何人推薦的是,如果你真的想使用空閒,仍然會打開一個終端/命令窗口來做真正的測試。 –

1

看到這個article

我引述:

如果您嘗試停止使用Ctrl-C組合一個CPython的程序 ,解釋 拋出一個KeyboardInterrupt異常。

它是有道理的,因爲線程睡着了10秒,所以例外不能拋出,直到10秒過去。但是,ctrl + c總是在shell中工作,因爲你試圖停止一個進程,而不是拋出python KeyboardInterrupt異常。

此外,請參閱此前回答question

我希望這有助於!

+0

那麼爲什麼KeyboardInterrupt通過Ctrl + C在shell中工作,而不是在Idle中? – cssndrx

+0

我編輯了帖子。看到新的變化。 – Sam

+0

我不認爲我理解你在說什麼...你在說什麼Ctrl + C在空閒中做什麼?另外,shell中的Ctrl + C確實會導致KeyboardInterrupt異常 – cssndrx