python - 重写 threading.Thread 对象中的 start() 函数有什么问题?

标签 python multithreading

我想要一个像控制台一样工作的主程序,我可以在其中调用其他进程(无限循环),并在输入某些命令时有选择地终止它们。

为此我创建了这个类:

class RunInThread(threading.Thread):
    def __init__(self, function):
        self.function = function
        self.kill_pill = threading.Event()
        threading.Thread.__init__(self)

    def start(self): # This is controversial.
        self.__init__(self.function)
        threading.Thread.start(self)    

    def stop(self):
        self.kill_pill.set()

    def run(self):
        while not self.kill_pill.is_set():
            self.function()

thread.Thread 的文档指出,只有 __init__()run() 方法应该被重写。 我的代码有什么明显的问题吗?它按照我预期的方式工作,但由于它将运行很长时间,我需要确保不会造成任何内存问题。

编辑:

这个解决方案怎么样?:

class StoppableThread(threading.Thread):
    # threading.Thread class but can be stopped with the stop() method.
    def __init__(self, function):
        threading.Thread.__init__(self)
        self.function = function
        self.kill_pill = threading.Event()

    def stop(self):
        self.kill_pill.set()

    def run(self):
        while not self.kill_pill.is_set():
            self.function()

class RunInThread():
    def __init__(self, function, prnt=False):
        self.function = function
        self.running = False
        self.prnt = prnt

    def start(self):
        if not self.running:
            self.thread = StoppableThread(self.function)
            self.thread.start()
            self.running = True
        else:
            if self.prnt:
                print('Thread already running.')

    def stop(self):
        self.thread.stop()
        self.running = False

最佳答案

如果您想了解哪些内容可能会损坏,我建议您查看 the implementation of Thread类。

除此之外,Thread.__init__() 初始化一个 Event() 对象以检测线程启动和关闭、管理清理钩子(Hook)/回调、一些内部锁定对象,并将线程注册到列表中这样你就可以内省(introspection)正在运行的线程。通过调用 Thread.__init__(),这些变量会被重新初始化,并破坏许多这些功能的内部机制。

可能会出现什么问题?我没有测试其中任何一个,但通过浏览 threading.py,这些可能是我预计可能会出错的一些事情:

  • 您的 python 进程现在将运行一个未出现在 enumerate_thread() 中的操作系统线程
  • 现在,多个操作系统线程在调用 current_thread() 时将返回相同的 Thread 对象,这也可能会破坏 threadlocal 以及任何依赖于 threadlocal 的内容
  • Thread.join() 依赖于一些内部锁,这些锁现在可能会导致线程调用不安全
  • 未处理的接收可能会转到错误的异常 Hook 处理程序
  • register_at_fork 和关闭处理程序可能会混淆

换句话说,不要试图偷偷摸摸。为每个要启动的线程创建一个新的 Thread 对象。

Thread 类花费精力试图防止您意外地调用 start() 两次是有充分理由的。不要试图颠覆这一点。

关于python - 重写 threading.Thread 对象中的 start() 函数有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59541935/

相关文章:

c++ - 使基于选择的循环尽可能响应

python - Chaco 和 PyQt 无法发出信号

与 Python 3.1.x 相比,Python 3.2 非常慢

python - numpy.random.multinomial 错误输出?

python - 如何根据pandas中另一个数据框中的条件更新数据框

python - 如何在Python中通过shell导入sql?

java - BeanFactory 未初始化或已关闭 - 在通过 ApplicationContext 访问 bean 之前调用 'refresh'

python - 如何触发Raspberry Pi 3从服务器采取行动

python - 在保留向后兼容性的情况下重命名函数

multithreading - Perl 有哪些推荐的多线程管理器?