检测主进程是否已从后台进程退出



我有一个后台进程与主进程一起运行,它使用Queue进行通信(使用多处理,而不是多线程(。主进程不断运行,后台线程每个队列项运行一次,因此即使它被积压,它仍然可以赶上。与其使用主脚本关闭(我已经为此启用了daemon(,我希望它运行直到队列为空,然后保存并退出。

它是这样开始的:

q_send = Queue()
q_recv = Queue()
p1 = Process(target=background_process, args=(q_send, q_recv))
p1.daemon = True
p1.start()

以下是后台进程当前运行的运行方式:

while True:
    received_data = q_recv.get()
    #do stuff

我考虑的一种方法是将循环切换为一直运行,但在尝试读取队列之前检查队列的大小,如果它为空,请等待几秒钟,然后再尝试。不过有几个问题。重点是它将为每个项目运行一次,因此如果有 1000 个排队的命令,则在每个命令之前检查队列大小似乎有点低效。此外,主进程在不发送更新的情况下可以持续多长时间没有真正的限制,因此我必须将超时设置得相当高,而不是在连接断开和队列清空时立即退出。由于后台线程使用高达 2gb 的 ram,它可能会尽快退出。

这也会使它看起来更加混乱:

afk_time = 0
while True:
    if afk_time > 300:
        return
    if not q_recv.qsize():
        time.sleep(2)
        afk_time += 2
    else:
        received_data = q_recv.get()
        #do stuff

我遇到了is_alive(),并认为也许从current_process()获取主进程可能会起作用,但是当我尝试将其发送到队列时,它给出了一个选择错误。

Queue.get有一个关键字参数timeout,该参数确定队列为空时等待项目的时间。如果在超时过后没有可用项,则会引发Empty异常。

从队列中删除并返回项目。如果可选的 args 块为 true,超时为 None (默认值(,则在必要时阻止,直到项目可用。如果超时为正数,则最多阻止超时秒数,并在该时间内没有可用项时引发 Empty 异常。否则(块为 false(,如果立即可用,则返回一个项目,否则引发 Empty 异常(在这种情况下忽略超时(。

因此,您可以排除该错误并脱离循环:

try:
    received_data = q_recv.get(timeout=300)
except queue.Empty:
    return

相关内容

  • 没有找到相关文章

最新更新