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

时间:2017-06-29 20:31:06

标签: python multiprocessing

我有一个后台进程与主要进程一起运行,它使用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()获取主要流程可能会有效,但当我尝试将其发送到队列时,它会发出错误选择错误。

1 个答案:

答案 0 :(得分:1)

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

  

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

所以你可以除了那个错误并突破循环:

try:
    received_data = q_recv.get(timeout=300)
except queue.Empty:
    return
相关问题