python模块threading有一个对象Thread
,用于在不同的线程中运行进程和函数。此对象具有start
方法,但没有stop
方法。我调用简单Thread
方法无法阻止stop
的原因是什么?我可以想象使用join
方法不方便的情况...
答案 0 :(得分:9)
start
可以是通用的并且有意义,因为它只是触发了线程的目标,但是泛型stop
会做什么?根据您的线程正在做什么,您可能必须关闭网络连接,释放系统资源,转储文件和其他流,或任何其他自定义,非平凡的任务。任何能够以通用方式完成大部分这些事情的系统都会给每个线程增加太多的开销,而这些开销是不值得的,并且会非常复杂并且在特殊情况下会突然发现它几乎不可能工作用。您可以在主线程中跟踪所有创建的线程而不join
,然后检查它们的运行状态,并在主线程自行关闭时传递它们某种终止消息。
答案 1 :(得分:6)
绝对可以实现Thread.stop
方法,如以下示例代码所示:
import threading
import sys
class StopThread(StopIteration): pass
threading.SystemExit = SystemExit, StopThread
class Thread2(threading.Thread):
def stop(self):
self.__stop = True
def _bootstrap(self):
if threading._trace_hook is not None:
raise ValueError('Cannot run thread with tracing!')
self.__stop = False
sys.settrace(self.__trace)
super()._bootstrap()
def __trace(self, frame, event, arg):
if self.__stop:
raise StopThread()
return self.__trace
class Thread3(threading.Thread):
def _bootstrap(self, stop_thread=False):
def stop():
nonlocal stop_thread
stop_thread = True
self.stop = stop
def tracer(*_):
if stop_thread:
raise StopThread()
return tracer
sys.settrace(tracer)
super()._bootstrap()
################################################################################
import time
def main():
test = Thread2(target=printer)
test.start()
time.sleep(1)
test.stop()
test.join()
def printer():
while True:
print(time.time() % 1)
time.sleep(0.1)
if __name__ == '__main__':
main()
Thread3
类似乎运行代码的速度比Thread2
类快大约33%。
答案 2 :(得分:5)
以可靠的方式杀死线程并不是一件容易的事。想想所需的清理:哪些锁(可能与其他线程共享!)应该自动释放?否则,你很容易陷入僵局!
更好的方法是自己实现正确的关闭,然后设置
mythread.shutdown = True
mythread.join()
停止线程。
当然你的主题应该像
那样while not this.shutdown:
continueDoingSomething()
releaseThreadSpecificLocksAndResources()
经常检查关机标志。或者,您可以依靠特定于操作系统的信令机制中断线程,捕获中断,然后清理。
清理是最重要的部分!
答案 3 :(得分:1)
停止线程应该由程序员来实现。比如设计你的线程来检查它有任何请求它立即终止。如果python(或任何线程语言)允许你只是停止一个线程,那么你将拥有刚刚停止的代码。这很容易出错等。
想象一下,如果您的线程在您杀死/停止它时将输出写入文件。然后该文件可能未完成并已损坏。但是,如果您简单地通知您希望它停止的线程,那么它可以关闭文件,删除它等等。您,程序员,决定如何处理它。 Python无法猜测你。
我建议阅读多线程理论。一个不错的开始:http://en.wikipedia.org/wiki/Multithreading_(software)#Multithreading
答案 4 :(得分:0)
在某些平台上,您无法强行“停止”线程。这样做也很糟糕,因为那时线程将无法清理分配的资源。当线程正在做一些重要的事情时,可能会发生这种情况,比如I / O.