给定可停止的伪原子工作单元,在Python中制作可停止线程的“正确”方法是什么?

时间:2012-10-29 16:03:15

标签: python multithreading decorator

我正在用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()

3 个答案:

答案 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上进行工作人员的通信和控制,例如同步