我想要一个像控制台一样工作的主程序,我可以在其中调用其他进程(无限循环),并在输入某些命令时有选择地终止它们。
为此我创建了这个类:
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/