2013-10-14 68 views
1

我編寫了一個小腳本,它在Python中做了非常耗時的工作,並且包含了一個信號處理模塊,用於偵聽SIGINT,SIGQUIT和SIGINFO,打印SIGQUIT或SIGINFO由用戶輸入,並在輸入SIGINT(CTRL-C)時中止程序。代碼極其潦草,因爲我在幾分鐘內就入侵了它,並偷走了一些外國代碼 - 不用擔心,只要我(或者說你,因爲我被卡住了)發現了這個bug,我就馬上清理它:退出Python中的外部模塊(信號處理)

def setup_signals(progress_bar): 
import signal 
import sys 

def progress(*args): 
    print(progress_bar) 

def killitwithfire(*args): 
    print("[x] User interrupted with CTRL-C. Aborting.") 
    sys.exit(0) 

for sig in (signal.SIGINFO, signal.SIGQUIT): 
    signal.signal(sig, progress) 
for sig in (signal.SIGINT,): 
    signal.signal(sig, killitwithfire) 
print("Sig handlers built:\n Press Ctrl+T(BSD/OS X) or Ctrf+4(Linux) for progress.") 
print("Press CTRL-C to abort.") 

現在,問題是,當輸入CTRL-C時,會顯示killitwithfire()中的消息 - 對不良引用感到抱歉 - 將被打印,但不會退出。

執行此代碼的代碼位於try/catch /塊內。如果這是問題,我該如何退出該信號處理模塊?如果這不是問題,那麼它是什麼?

+0

對不起,縮進完全關閉。 def setup_signals包括它下面的所有代碼。 – hellerve

回答

1

信號處理不在主線程中完成,所以調用sys.exit()不會做停止主線程的技巧。實際上,調用它只會引發一個特殊的內部異常(SystemExit),如果未被捕獲,它將終止當前線程。沒有用python內部的標準方式發信號通知一個線程請求終止,所以結束信號處理線程不會終止主線程。

您有幾種選擇。

一個是檢查一個條件(全局變量或threading.Condition或類似的)的長程線程內,如果這表明「請終止」,然後停止循環。

另一種方法是使用操作系統的設施,並通過其所有線程終止進程(例如向自己發送一個你不知道的信號,例如SIGKILL)。

+0

非常感謝。那不是我希望的答案,但至少我可以做一個解決方法。 – hellerve