2014-04-22 64 views
0

我有一個Python 2.7圖形用戶界面,其中通過按一個按鈕生成一個圖。繪圖的計算需要幾秒鐘。通過使用threading.Thread,GUI在計算過程中不被阻塞。殺死一個線程(通過使用多處理?)

如果我想在第一次計算仍在運行時重新計算,將導致混亂。我發現不可能殺死一個線程。我讀過關於多處理,但不幸的是我沒有成功創建一個簡單的工作示例。

是否有任何建議如何處理這個問題或任何人都可以給我看一個簡短的多處理示例?

感謝

回答

1

這是更好,如果你在你的線程,告訴它停止本身,而不是試圖從外面殺了它添加一個標誌。請參閱this answer

0

你不能殺死任何編程語言的線程。當然,使用C語言的線程可能會被殺死,但最有可能導致程序崩潰,導致分段違例或其他錯誤。這是因爲當線程殺死線程使用的任何資源時都無法釋放。

Python沒有可能這樣做(殺死線程)。爲了安全地停止線程,您可以使用定期檢查主線程循環的threading.Event()。例如可停止的線程模板:

import abc 
import threading 
import logging 

class StopableThread(threading.Thread): 

    __metaclass__ = abc.ABCMeta 

    def __init__(self, name=None, start=False, init=True, manager=None): 
     """ 
     :param str name: Name of the new thread 
     :param bool start: Force thread to start at the __init__() exit 
     """ 
     super(StopableThread, self).__init__(name=name) 

     self.__event_thread_started = threading.Event() 
     """:type: threading._Event""" 

     self.__is_terminated = False 
     """ 
     :param: True - if thread was terminated after working 
     :type: bool 
     """ 

     self.__is_fatal_error = False 
     """ 
     :param: True if unhandled exception was occurred during thread working 
     :type: bool 
     """ 

     self.__is_initialized = init 
     """ 
     :param: Flag indicate that thread successfully initialized and can be started 
     :type: bool 
     """ 

     self._event_terminate_request = threading.Event() 
     """ 
     :param: if Event is set then thread will be stopped 
     :type: threading._Event 
     """ 

     if start: 
      self.start() 

    def run(self): 
     self.__event_thread_started.set() 

     try: 
      self.payload() 
     except: 
      logging.error("Unhandled exception has been occurred in thread %s:\n%s" % 
          (self.name, traceback.format_exc())) 
      self.__is_fatal_error = True 
     finally: 
      self.__is_terminated = True 

    def terminate(self, timeout=None, block=True): 
     """ 
     Set flag to stop payload() function and wait until thread not finished. 

     :param float or None timeout: How long to wait until thread not finished. 
             None mean forever. 
     :param bool block: False - terminate will not wait until thread finished. 
     :return: True - if thread was terminated 
     :rtype: bool 
     """ 
     logging.debug("Terminate request for thread %s" % self.name) 
     self._event_terminate_request.set() 
     if block and self.__event_thread_started.isSet(): 
      self.join(timeout) 
     return self.__is_terminated 

    @property 
    def is_terminated(self): 
     return self.__is_terminated 

    @property 
    def is_initialized(self): 
     return self.__is_initialized 

    @property 
    def is_fatal_error(self): 
     return self.__is_fatal_error 

    @abc.abstractmethod 
    def payload(self): 
     pass 

class ImplementedThread(StopableThread): 
    def __init__(self, name): 
     super(ImplementedThread, self).__init__(name=name) 

    def payload(): 
     while not self._event_terminate_request.isSet(): 
      # Do something useful 
      pass