【问题标题】:Check if parent thread is running检查父线程是否正在运行
【发布时间】:2012-10-27 21:17:20
【问题描述】:

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

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 方法,但我不确定如何使用它。

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    您可以使用以下行:

    threading.main_thread().is_alive()
    

    【讨论】:

      【解决方案2】:

      如果您以某种方式与子线程共享父线程对象,则可以使用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()
      

      【讨论】:

        【解决方案3】:

        您可以将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()
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-05
          • 2015-05-28
          相关资源
          最近更新 更多