11

我正在用 Python 编写一个线程程序。这个程序被用户(CRTL+C)交互,以及其他程序发送各种信号中断非常频繁,所有这些都应该以各种方式停止线程操作。线程按顺序执行一堆工作单元(我称它们为“原子”)。

每个原子都可以快速安全地停止,因此使线程本身停止是相当微不足道的,但我的问题是:什么是“正确”或规范的方式来实现可停止的线程,给定可停止的伪原子工作做完了?

我应该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()
4

3 回答 3

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()
于 2012-10-29T16:18:43.327 回答
0

创建一个“线程 x 应该继续处理”标志,当你完成线程时,将该标志设置为 false。

直接杀死线程被认为是不好的形式,因为您可能会完成一小部分工作。

于 2012-10-29T16:16:42.697 回答
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:th 秒触发一次

该库非常新,GitHub https://github.com/fa1k3n/ants.git上的工作正在进行中

未来的工作包括添加一个colony让多个工作人员处理相同数据的不同部分的工作,还计划一个queen工作人员通信和控制,如同步

于 2019-05-03T16:27:34.500 回答