我有一个产生4个线程的程序,这些线程需要无限期地保持运行,如果其中一个崩溃,我需要知道,所以我可以重新启动。
如果我使用带有4个数字的列表并使用队列将其传递给每个线程。然后所有每个线程都要做的是重置其在计时器中的部分,而主线程将其计数。
所以队列永远不会是空的,只有一个值可以变为0,然后如果发生这种情况,那么主线程知道它的孩子没有响应,它可以相应地行动。
但是每次我从队列中得到.get(),它都会变空,所以我必须从队列中获取,存储到变量中,修改变量并将其放回队列中。
使用像这样的队列来监视看门狗是否正常。
答案 0 :(得分:1)
如果您使用的是Thread
,则可以定期检查threading.enumerate
,以确保您拥有正确数量和类型的线程。
但是,同样,将事物传递到从线程返回的队列中是一种技术,我至少看到用于确保线程仍在运行。所以,如果我正确理解你,你所做的并不是完全疯狂。
您的“线程必须偶尔重新设置其发送者”可能更有意义的是,Queue
列表中每个Thread
都应尽快响应。这取决于你的线程是否实际上正在处理过程密集的东西,或者它们是否仅因接口原因而背景化。如果他们不花费他们所有的时间做数学,你可以做类似的事情:
def guarded_thread(sentinal_queue, *args):
while True:
try:
sentinal_queue.get_nowait()
sentinal_queue.put('got it')
except Queue.Empty:
# we just want to make sure that we respond if we have been
# pinged
pass
# do actual work with other args
def main(arguments):
queues = [Queue() for q in range(4)]
threads = [(Thread(target=guarded_thread, args=(queue, args)), queue)
for queue, args in zip(queues, arguments)]
for thread, queue in threads:
thread.start()
while True:
for thread, queue in threads:
queue.put(True)
for thread, queue in threads:
try:
response = queue.get(True, MAX_TIMEOUT)
if response != 'got it':
# either re-send or restart the thread
except Queue.Empty:
# restart the thread
time.sleep(PING_INTERVAL)
请注意,您还可以使用不同的请求/响应队列来避免使用不同类型的sentinal值,这取决于您的实际代码,哪一个看起来不那么疯狂。