2010-10-26 23 views
3

我有MacOS X上的Python 2.6和多線程操作。下面的測試代碼工作正常,並關閉應用程序上按Ctrl-C:Python在多線程程序中忽略SIGINT - 如何解決這個問題?

import threading, time, os, sys, signal 
def SigIntHandler(signum, frame) : 
    sys.exit(0) 
signal.signal(signal.SIGINT, SigIntHandler) 
class WorkThread(threading.Thread) : 
    def run(self) : 
    while True : 
     time.sleep(1) 
thread = WorkThread() 
thread.start() 
time.sleep(1000) 

但是,如果我只能改變一個字符串,加入一些實際工作,以工作線程,應用程序將永遠不會在按Ctrl-C終止:

import threading, time, os, sys, signal 
def SigIntHandler(signum, frame) : 
    sys.exit(0) 
signal.signal(signal.SIGINT, SigIntHandler) 
class WorkThread(threading.Thread) : 
    def run(self) : 
    while True : 
     os.system("svn up") # This is really slow and can fail. 
     time.sleep(1) 
thread = WorkThread() 
thread.start() 
time.sleep(1000) 

是否可以修復它,或python不打算與線程一起使用?

+0

我更新了我的答案。 – 2010-10-26 22:45:16

回答

2

一對夫婦的事情,可能會導致您的問題:

  1. 按Ctrl-C也許是被抓svn,這是忽略它。
  2. 您正在創建一個非守護線程的線程,然後退出該進程。這將導致進程等到線程退出 - 它永遠不會。你需要使線程成爲一個守護進程,或者給它一個終止它的方法,並且在退出前給它一個join()。雖然它似乎總是停止在我的Linux系統上,但MacOS X的行爲可能會有所不同。

Python的作品不夠用線程:-)

更新:你可以嘗試使用subprocess,建立子進程,使文件句柄不能被繼承,並設置孩子的標準輸入到子進程。管。

+0

「Ctrl- C可能被svn捕獲,而忽略它「 - 非常有趣。是否有什麼辦法可以從我的python代碼啓動」svn up「,所以輸入是python而不是svn? – grigoryvp 2010-10-26 13:58:26

2

我不是Python專家,但很快就讀了文檔,得出了一些結論。

1)調用os.system()會產生一個新的子shell,不鼓勵。相反,應該使用子流程模塊。 http://docs.python.org/release/2.6.6/library/os.html?highlight=os.system#os.system

2)threading模塊似乎並沒有給一大堆控制的線程,也許嘗試使用thread模塊,至少有一個thread.exit()功能。同樣來自threading文檔here它說,虛擬線程可以創建的,它總是活和後臺,而且

"… the entire Python program exits when only daemon threads are left." 

所以,我會想象,至少你需要做的是信號當前正在運行的線程,他們在退出主線程之前需要退出,或者在ctrl-c上加入它們以允許它們完成(雖然這顯然與ctrl-c相矛盾),或者可能只是使用subprocess模塊來產生svn up就可以做到這一點。

+0

「線程模塊似乎沒有給予線程很多控制,也許嘗試使用線程模塊」 - 「線程」基於'線程',它們實際上是相同的:( – grigoryvp 2010-10-26 10:37:33

2

您可能根本不需要線程。

嘗試使用Python的subprocess模塊,或者甚至Twisted的process support