2012-11-09 35 views
3

我想給Thread子類添加一個新的方法,這樣我就可以告訴我的工作線程優雅地退出。就像這樣:向Python Thread類添加新方法是否安全?

class MyThread(threading.Thread): 
    def __init__(self): 
     ... 
     self.__stop_signal = False 
     self.__signal_lock = threading.Lock() 
     ... 

    def run(self): 
     ... 
     self.__signal_lock.acquire(True) 
     stop_signal = self.__stop_signal 
     self.__signal_lock.release() 
     if stop_signal: 
      return 
     ... 

    def stop_elegantly(self): 
     self.__signal_lock.acquire(True) 
     self.__stop_signal = True 
     self.__signal_lock.release() 

然後就是它的安全做到這一點?:

thread = MyThread() 
thread.start() 
... 
thread.stop_elegantly() 

感謝。

回答

1

是的,它看起來很好。事實上,你可以做到更加「優雅」與:

def stop_elegantly(self): 
    with self.__signal_lock: 
     self.__stop_signal = True 

其實我不認爲你甚至需要一個鎖定訪問成員變量,因爲還會有分配的每個實例單獨一個你子類。例如,請參見此answer,它將stop()方法添加到threading.Thread子類。

+0

謝謝。關於鎖,我認爲在某些極端情況下,鎖是必要的(例如,當內存中的值與緩存中的值不同時)。因爲在這裏使用鎖有點過分了。 – kkpattern

+0

@kkpattern:在我看來,CPU硬件會照顧任何內存vs單個線程內的緩存內存差異。無論如何,感謝您選擇我的答案。順便說一句,如果你認爲這是值得的,那麼在這裏習慣上也會迴應你接受的答案。 – martineau

0
self.__signal_lock.acquire(True) 
    stop_signal = self.__stop_signal 
    self.__signal_lock.release() 

上面的代碼是在循環?如果是的話,我認爲它運作良好。

+0

對不起,我的意思是從另一個線程調用stop_elegantly()方法是安全的。 Python文檔說,除了'run()'和'__init __()'之外,它們不會重寫其他方法,但是它沒有提到添加新方法和調用它的任何內容。 – kkpattern

+0

嗯。 stop_elegantly()被代碼中的主線程調用,不是嗎?我認爲主線是上面評論中的另一個線索。 –

+0

是的,你是對的。在Thread線程中調用方法是很安全的,比如'join()'。我想知道調用一個方法將自己添加到Thread子類中也是安全的。 – kkpattern

相關問題