为什么python threading.Thread对象有'start',但不是'stop'?

时间:2013-01-23 14:37:39

标签: python multithreading

python模块threading有一个对象Thread,用于在不同的线程中运行进程和函数。此对象具有start方法,但没有stop方法。我调用简单Thread方法无法阻止stop的原因是什么?我可以想象使用join方法不方便的情况...

5 个答案:

答案 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.