繁体   English   中英

如何检测线程是否死亡,然后重新启动它?

[英]How do I detect if a thread died, and then restart it?

我有一个应用程序启动一系列线程。 有时,其中一个线程死亡(通常是由于网络问题)。 如何正确检测线程崩溃并重新启动该线程? 这是示例代码:

import random
import threading
import time

class MyThread(threading.Thread):
    def __init__(self, pass_value):
        super(MyThread, self).__init__()
        self.running = False
        self.value = pass_value

    def run(self):
        self.running = True

        while self.running:
            time.sleep(0.25)

            rand = random.randint(0,10)
            print threading.current_thread().name, rand, self.value
            if rand == 4:
                raise ValueError('Returned 4!')


if __name__ == '__main__':
    group1 = []
    group2 = []
    for g in range(4):
        group1.append(MyThread(g))
        group2.append(MyThread(g+20))


    for m in group1:
        m.start()

    print "Now start second wave..."

    for p in group2:
        p.start()

在这个例子中,我启动4个线程然后我开始4个线程。 每个线程随机生成一个介于0和10之间的int 。如果该int4 ,则会引发异常。 请注意,我没有join线程。 我想要group1group2线程列表都在运行。 我发现如果我加入了线程,它会等到线程终止。 我的线程应该是一个守护进程,因此应该很少(如果有的话)遇到ValueError Exception,这个示例代码正在显示并应该不断运行。 通过加入它,下一组线程不会开始。

如何检测特定线程是否已死亡并重新启动该线程?

for p in group2循环中的for p in group2后面尝试了以下循环。

while True:
    # Create a copy of our groups to iterate over, 
    # so that we can delete dead threads if needed
    for m in group1[:]:
        if not m.isAlive():
            group1.remove(m)
            group1.append(MyThread(1))

    for m in group2[:]:
        if not m.isAlive():
            group2.remove(m)
            group2.append(MyThread(500))

    time.sleep(5.0)

我从这个问题中采用了这种方法。

这个问题是isAlive()似乎总是返回True ,因为线程永远不会重启。

编辑

在这种情况下使用多处理更合适吗? 我找到了这个教程。 如果我需要重新启动进程,是否更适合使用单独的进程? 似乎重启线程很困难。

在评论中提到我应该对线程检查is_active() 我没有在文档中看到这一点,但我确实看到了我目前正在使用的isAlive 正如我上面提到的,这会返回True ,因此我永远无法看到线程已经死亡。

您可能会尝试进行尝试,除非您希望它崩溃的地方(如果它可以在任何地方,您可以围绕整个运行函数执行)并且具有一个具有其状态的指示符变量。

如下所示:

class MyThread(threading.Thread):
    def __init__(self, pass_value):
        super(MyThread, self).__init__()
        self.running = False
        self.value = pass_value
        self.RUNNING = 0
        self.FINISHED_OK  = 1
        self.STOPPED = 2
        self.CRASHED = 3
        self.status = self.STOPPED

    def run(self):
        self.running = True    
        self.status = self.RUNNING


        while self.running:
            time.sleep(0.25)

            rand = random.randint(0,10)
            print threading.current_thread().name, rand, self.value

            try:
                if rand == 4:
                    raise ValueError('Returned 4!')
            except:
                self.status = self.CRASHED

然后你可以使用你的循环:

while True:
    # Create a copy of our groups to iterate over, 
    # so that we can delete dead threads if needed
    for m in group1[:]:
        if m.status == m.CRASHED:
            value = m.value
            group1.remove(m)
            group1.append(MyThread(value))

    for m in group2[:]:
        if m.status == m.CRASHED:
            value = m.value
            group2.remove(m)
            group2.append(MyThread(value))

time.sleep(5.0)

我有一个类似的问题,偶然发现了这个问题。 我发现join接受了一个超时参数,并且一旦线程加入,is_alive将返回False。 所以我对每个线程的审计是:

def check_thread_alive(thr):
    thr.join(timeout=0.0)
    return thr.is_alive()

这为我检测线程死亡。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM