我有一个Python 2.7图形用户界面,其中通过按一个按钮生成一个图。绘图的计算需要几秒钟。通过使用threading.Thread,GUI在计算过程中不被阻塞。杀死一个线程(通过使用多处理?)
如果我想在第一次计算仍在运行时重新计算,将导致混乱。我发现不可能杀死一个线程。我读过关于多处理,但不幸的是我没有成功创建一个简单的工作示例。
是否有任何建议如何处理这个问题或任何人都可以给我看一个简短的多处理示例?
感谢
我有一个Python 2.7图形用户界面,其中通过按一个按钮生成一个图。绘图的计算需要几秒钟。通过使用threading.Thread,GUI在计算过程中不被阻塞。杀死一个线程(通过使用多处理?)
如果我想在第一次计算仍在运行时重新计算,将导致混乱。我发现不可能杀死一个线程。我读过关于多处理,但不幸的是我没有成功创建一个简单的工作示例。
是否有任何建议如何处理这个问题或任何人都可以给我看一个简短的多处理示例?
感谢
这是更好,如果你在你的线程,告诉它停止本身,而不是试图从外面杀了它添加一个标志。请参阅this answer。
你不能杀死任何编程语言的线程。当然,使用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