2

我想知道如何检查父线程是否仍然存在/卡住。基本上我有一个父线程向孩子发送命令。如果父线程死亡或遇到死锁条件,我不希望孩子继续生存。以下是迄今为止我实现的基本框架。

from Queue import Queue
from threading import Thread

    class myClass:

        def __init__(self):

            self.currentCommand = Queue()           
            t = Thread(target=self._run)
            t.start()            

        def close(self):
            self._sendCommand("close")

        def _run(self):
            while True:
                if self.currentCommand.empty():
                    pass
                    #do some task
                else:
                    command = self.currentCommand.get()
                    if command == "close":
                        #clean up
                        self.currentCommand.task_done()
                        break
                    else:
                        #do command task
                        self.currentCommand.task_done()

        def _sendCommand(self, command):
            self.currentCommand.put(command)
            self.currentCommand.join()

我的一个想法是定期从父母那里向孩子发送计算机时间。如果时间大于设定值,孩子就会死亡。有没有更简单或更有效的方法?同样在 python 文档中,线程类中有一个 isAlive 方法,但我不确定如何使用它。

4

3 回答 3

2

您可以将一个Event对象向下传递给子线程,它可以检查父线程是否指示退出。然后,您只需将关键部分包装在父线程中,finally无论如何都会设置该位:

import time
from threading import Thread, Event


def child(quit):
    for _ in xrange(10):
        if quit.isSet():
            print "Parent is dead. Leaving child."
            return

        print "Child alive"
        time.sleep(.5)

def parent():
    quitEvent = Event()
    t = Thread(target=child, args=(quitEvent,))
    t.start()

    try:
        time.sleep(2)
        raise Exception("Parent thread raises exception")
    finally:
        quitEvent.set()

    t.join()


if __name__ == "__main__":
    t = Thread(target=parent, args=())
    t.start()
    t.join()

尽管父线程在它自己的工作期间死锁的问题可能需要像您建议的那样采用“心跳”方法,它会定期指示它处于活动状态。您可以使用传递给子级的队列来执行此操作,也可以继续使用 Event 对象。父母会定期设置事件,孩子会期望它以一定的间隔设置,然后会立即清除它。

下面是一个使用Event心跳的例子,在父节点可能死锁并且没有签入的情况下:

def child(heartbeat):
    for _ in xrange(10):
        if not heartbeat.isSet():
            print "Parent is dead. Leaving child."
            return

        heartbeat.clear()

        print "Child alive"
        time.sleep(1)

def parent():
    heartbeat = Event()
    heartbeat.set()

    t = Thread(target=child, args=(heartbeat,))
    t.start()

    i = 0
    while i < 20:
        print "Parent alive"
        i += 1
        heartbeat.set()
        time.sleep(.1)

    print "Parent done looping...pretending to be deadlocked"
    time.sleep(5)

    t.join()

由于父母正在做自己的工作,它正在设置心跳位。孩子定期检查这个位。如果它发现父节点未设置,则假定它已死并退出。您需要建立一个合适的心跳间隔。父母需要比孩子更频繁地检查,否则孩子可能很快就会检查并认为父母已经离开了。

于 2012-11-07T19:06:12.253 回答
1

isAlife如果您以某种方式与孩子共享父线程对象,则可以使用:

parent_thread = None

def child():
   while True:
       time.sleep(1)
       if not parent_thread.isAlive():
           break
       print('child alife')


def parent():
    t = threading.Thread(target=child)
    t.start()
    for i in range(10):
        print('parent alife')
        time.sleep(1)

parent_thread = threading.Thread(target=parent)
parent_thread.start()
于 2012-11-07T19:33:13.530 回答
0

您可以使用以下行:

threading.main_thread().is_alive()
于 2021-12-22T13:55:36.877 回答