2011-02-16 137 views
3

可能重複:
Is there any way to kill a Thread in Python?的Python:如何終止阻塞線程

所以這個問題是一個跟進到以前發佈的解決方案。基本上它涉及編程方式終止一個線程:http://sebulba.wikispaces.com/recipe+thread2

然而,它不工作......我想知道如果有人可以解釋如何可以終止一個阻塞的線程?我唯一的猜測是,我沒有提供正確的線程ID,但我做了一些測試,我很確定我可以使用標識

如果它是線程ID,我該如何去獲得正確的線程ID?

測試代碼:

class BlockingTestThread(Thread): 

    def __init__(self): 
     self._running_flag = False 
     Thread.__init__(self, target=self.test_method) 

    def test_method(self): 
     try: 
      while(not self.stopped()): 
       self._running_flag = True 
       time.sleep(100) 
     finally: 
       self._running_flag = False 


def _async_raise(tid, exctype): 
    '''Raises an exception in the threads with id tid''' 
    if not inspect.isclass(exctype): 
     raise TypeError("Only types can be raised (not instances)") 

    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype)) 
    time.sleep(0.1) 



if __name__ == "__main__": 
    thread = BlockingTestThread() 
    thread.start() 

    _async_raise(thread.ident, SystemExit) 
    print "Joining thread" 
    thread.join() 
    print "Done Joining thread" 
    #will never get here! 
+0

順便說一句,我的黑客是interup連接,接收機正在監聽,我基本上只是抓住它並退出循環。它的醜陋,但我找不到另一種方式。 – Nix

+0

你同意它是重複的嗎? –

回答

4

下面是一個更好的方法來做到這一點,使用事件的「等待」命令,並假設你想使用睡眠。

class BlockingTestThread(Thread): 
    def __init__(self): 
     self._running_flag = False 
     self.stop = threading.Event() 
     Thread.__init__(self, target=self.test_method) 

    def test_method(self): 
     try: 
      while(not self.stop.wait(1)): 
       self._running_flag = True 
       print 'Start wait' 
       self.stop.wait(100) 
       print 'Done waiting' 
     finally: 
       self._running_flag = False 

    def terminate(self): 
     self.stop.set() 

if __name__ == "__main__": 
    thread = BlockingTestThread() 
    thread.start() 

    time.sleep(2) 
    print 'Time sleep 2' 
    thread.terminate() 
    print "Joining thread" 
    thread.join() 
    print "Done Joining thread" 

很顯然,你將需要來包裝你的阻塞線程在使用上述模式的東西,但如果你不能在另一種選擇是導致你的過程中拋出一個異常,在我們的例子中,我們基本上終止導致異常的基礎連接,並且如果設置停止標誌時發生異常,我們將忽略它。

0

你說得對有關IDENT,從文檔,IDENT變量不映射到線程ID,它只是一個參考 -

thread.get_ident( )

返回當前線程的'線程標識符'。這是一個非零整數。它的價值沒有直接的意義;它的目的是作爲一個魔術餅乾使用,例如索引線程特定數據的字典。當線程退出並創建另一個線程時,線程標識符可能會被回收。

請參閱http://bytes.com/topic/python/answers/45247-terminating-thread-parent重新:killing,不知道它是否正是你正在尋找不幸的。

+0

這個例子不會阻止....我猜它不可能... – Nix