我有一个Python 2.7 GUI,通过按下按钮生成绘图。绘图的计算需要几秒钟。通过使用threading.Thread,在计算过程中不会阻止GUI。
如果我想在第一次计算仍在运行时重新计算,则会导致混乱。我发现杀死一个帖子是不可能的。我已经阅读了有关多处理的内容,但不幸的是我没有成功创建一个简单的工作示例。
是否有任何建议如何处理问题,或者任何人都可以向我展示一个简短的多处理示例?
由于
答案 0 :(得分:1)
如果你在你的线程中添加一个标志来告诉它停止自己而不是试图从外面杀死它,那会更好。请参阅this answer。
答案 1 :(得分:1)
你不能用任何编程语言杀死线程。当然,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