Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么';在threading.Thread对象中重写start()函数有什么问题?_Python_Multithreading - Fatal编程技术网

Python 什么';在threading.Thread对象中重写start()函数有什么问题?

Python 什么';在threading.Thread对象中重写start()函数有什么问题?,python,multithreading,Python,Multithreading,我希望有一个像控制台一样工作的主程序,在那里我可以调用其他进程(无限循环),并在输入某些命令时选择性地杀死它们 为此,我创建了这个类: class RunInThread(threading.Thread): def __init__(self, function): self.function = function self.kill_pill = threading.Event() threading.Thread.__init__(s

我希望有一个像控制台一样工作的主程序,在那里我可以调用其他进程(无限循环),并在输入某些命令时选择性地杀死它们

为此,我创建了这个类:

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
的文档说明,只有
\uuuu init\uuuu()
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

如果你想知道什么东西会断裂,我建议你去上课

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

会出什么问题?我没有测试其中任何一个,但是通过浏览threading.py,我认为可能会出现一些问题:

  • 您的python进程现在将运行一个操作系统线程,该线程不会出现在enumerate_thread()中
  • 现在,多个OS线程在调用current_thread()时将返回同一个thread对象,这很可能还会中断threadlocal和任何依赖threadlocal的内容
  • join()依赖于一些内部锁,现在调用这些锁可能会变得不安全
  • 未处理的接收可能会转到错误的异常挂钩处理程序
  • 在\u分叉处注册\u,关闭处理程序可能会混淆
换句话说,不要偷偷摸摸。为要启动的每个线程创建一个新线程对象


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

目前,调用
self.\uuu init__(…
类方法内部不推荐使用,重复工作,可能会导致未知的副作用和毫无用处。我这样做是因为对于threading.Thread类,您只能启动一次对象,如果您尝试再次启动它,它会引发运行时错误。因此,我不是每次启动时都创建新的线程对象,而是重新初始化更优雅的解决方案将不胜感激。
它的工作方式符合我的预期
您打算做什么?编写的代码毫无意义。
线程。
线程。start()
不应该在每个线程实例中调用一次以上。也许您实际上打算实现一个?@Nacho“
.Thread
类只能启动一次对象":以这种方式克服此限制很棘手。我不建议这样做。运行代码不必从thread类派生。读取或写入数据也不必从file类派生。只需在单独的模块或类中编写代码,并将可调用的内容传递给
thread的构造函数即可。这就是我想知道的。谢谢!