我正在用Python编写一个线程程序。该程序经常被用户(CRTL + C)交互以及发送各种信号的其他程序中断,所有这些都应以各种方式停止线程操作。线程按顺序执行一系列工作单元(我称之为“原子”)。
每个原子都可以快速安全地停止,所以让线程本身停止是相当微不足道的,但我的问题是:实现可停止线程的“正确”或规范方法,给定stoppable,伪 - 要完成的工作原理?
我应该在每个原子之前轮询stop_at_next_check
标志(例如下面的例子)吗?我应该用标记检查的东西来装饰每个原子(基本上与示例相同,但隐藏在装饰器中)?或者我应该使用其他一些我没有想过的技术?
示例(简单停止标记检查):
class stoppable(Thread):
stop_at_next_check = False
current_atom = None
def __init__(self):
Thread.__init__(self)
def do_atom(self, atom):
if self.stop_at_next_check:
return False
self.current_atom = atom
self.current_atom.do_work()
return True
def run(self):
#get "work to be done" objects atom1, atom2, etc. from somewhere
if not do_atom(atom1):
return
if not do_atom(atom2):
return
#...etc
def die(self):
self.stop_at_next_check = True
self.current_atom.stop()
答案 0 :(得分:4)
标记检查似乎是正确的,但您错过了通过使用原子列表来简化它的机会。如果将原子放在列表中,则可以使用单个for循环而无需do_atom()
方法,并且检查位置的问题可以自行解决。
def run(self):
atoms = # get atoms
for atom in atoms:
if self.stop_at_next_check:
break
self.current_atom = atom
atom.do_work()
答案 1 :(得分:0)
创建“thread x should continue processing”标志,当你完成线程时,将标志设置为false。
直接杀死一个线程被认为是不好的形式,因为你可能会完成一小部分工作。
答案 2 :(得分:0)
有点晚了,但是我创建了一个小库,蚂蚁,解决了这个问题。在您的示例中,原子单位由工作人员
表示示例
from ants import worker
@worker
def hello():
print(“hello world”)
t = hello.start()
...
t.stop()
在上面的示例中,hello()将在一个单独的线程中运行,该线程在while True:
循环中被调用,从而尽可能快地吐出“ hello world”
您还可以触发事件,例如在上面的示例中,将hello.start()
替换为hello.start(lambda: time.sleep(5))
,每隔5秒就会触发一次
该库是一个非常新的库,正在GitHub https://github.com/fa1k3n/ants.git上进行工作
未来的工作包括添加colony
,以使多个工作人员处理同一数据的不同部分,还计划在queen
上进行工作人员的通信和控制,例如同步