2017-06-29 49 views
1

我有一个后台进程与主进程一起运行,它使用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个排队命令,在每个命令之前检查队列大小似乎有点低效。另外,主进程可以在没有发送更新的情况下运行多长时间没有实际限制,所以我必须将超时设置得相当高,而不是在连接中断时立即退出,并且队列清空。后台线程使用高达2g的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 

我碰到,并想也许正从current_process()主要过程可能会奏效,但是当我试图把它给了一个错误选择将其发送到队列。

回答

1

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

从队列中移除并返回一个项目。如果可选参数块为true并且超时时间为无(默认值),则在必要时阻止,直到项目可用。如果超时是一个正数,它将最多阻塞秒数,并在该时间内没有可用项目时引发空例外。否则(block为false),如果一个立即可用,则返回一个项目,否则引发Empty异常(在这种情况下超时被忽略)。

所以,你可以,除了错误和中断循环的:

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

感谢,如果没有更好的解决方案,我可能会做到这一点,仍然没有围绕我所提到的第二个问题得到但现在会做,我将不得不测试多久发送一次,以便尽可能降低超时时间:) – Peter

+0

@Peter您能否再次指出您的确切目标?我觉得我错过了一些东西(尤其是第二个问题)。为什么你想退出后台进程?如果主进程稍后将某些内容发送给队列呢? –

+0

我只希望它在主进程退出后结束,因为这意味着不会再添加队列项目。我所需要做的就是完成队列的处理,所以超时是一种解决方法,但最好的情况是,它会立即知道主进程已经结束,不需要任何超时。 – Peter