我認爲這將是那些簡單的問題,但它讓我感到莫名其妙。Python的time.sleep - 永不醒來
[STOP PRESS:我說得對。解決方案被發現。看到答案。]
我正在使用Python的unittest框架來測試多線程應用程序。好而直截了當 - 我有5個左右的工作線程監視一個公共隊列,還有一個生產線程爲他們製作工作項目。生產者線程正在被一個測試用例觸發。
在這個測試中,只有一個任務被放入隊列。它在測試中所做的處理僅僅是真實處理的一個存根,所以工作線程會在真正完成任務之前進行5秒鐘的休眠以模擬經過的時間,並且線程將準備好接受另一個任務。
到代碼的片段是:
logging.info("Sleep starting")
time.sleep(5)
logging.info("Waking up")
現在怪異的一部分。我看到「睡眠開始」日誌消息,但沒有喚醒消息。程序鎖定並且不響應鍵盤中斷(CTRL + C)。 CPU負載非常低。
我在Windows和Ubuntu(Python 2.6.2)中看到了同樣的問題。
我曾經思考過,如果發生異常並且被隱藏,所以我在第一行和第二行之間添加了「print 1/0」 - 我看到引發了除零錯誤。我把它移到睡眠之後,我從來沒有看到這個消息。
我想:「好吧,也許另一個線程正在嘗試同時記錄非常大的內容,它仍在緩衝,它在做什麼?」
那麼,到了這個時候,測試已經返回到unittest,它正在測試系統的狀態之前暫停等待線程前進。
logging.info("Test sleep starting")
time.sleep(0.25)
logging.info("Test waking up")
哇,看起來很熟悉。它以完全相同的方式凍結!第一條日誌消息出現,第二條不是。
我最近做了一個重大的單位重寫,所以我不能聲稱「我沒有碰任何東西」,但在變化中我看不到任何不適。
可疑的地方:
我使用Threading.Lock(因爲我不知道如何來思考GIL的安全,所以我堅持我知道,我什麼也看不見「deadlocky」大約包括。我的代碼。
我是新來的Python的單元測試框架。是不是有什麼它與重定向日誌或類似的可能模擬這些症狀?
不,我還沒有取代非標準時間模塊!
什麼會阻止線程喚醒?我還有什麼錯過了?
也許只是使用睡眠(秒)。 (從進口睡眠時間開始) Iam不是python用戶 - 只是使用谷歌,無法想象time.sleep(秒)命令可以凍結整個程序,而不是隻停留5秒.. 也許問題存在其他地方?在不同的線程或東西.. – TheChange 2010-02-26 14:58:12
@TheChange。我*我*使用完全相同的功能;只是一個簡單的命名空間差異。我也很難相信time.sleep()可以凍結整個程序(或者至少是兩個有問題的線程),這就是爲什麼我要求提示我應該在哪裏尋找。 – Oddthinking 2010-02-26 15:27:36
兩個建議:對一個虛擬函數使用monkey-patch'time.sleep',或者對一個簡單的打印文件使用monkey-patch'logging.info'。嘗試兩種方法,看看有什麼有用的行爲改變。也可以嘗試在監視CPU的同時按住Ctrl-C(自動重複),看看是否可以檢測到該進程中的任何活動......這意味着它確實存在,但有些東西在吞嚥信號。 – 2010-02-26 20:09:00