为什么从关闭的 multiprocessing.Queue 获取不会引发任何错误?

时间:2021-06-10 14:04:20

标签: python multithreading queue python-multiprocessing

我正在尝试进行一些多处理。

import multiprocessing

def func(foo,q):
  for i in foo:
    do something
    q.put(something)
  q.close()

q=multiprocessing.Queue()
p=multiprocessing.Process(target=func,args=(foo,q))
p.start()
while True:
  try:
    q.get()
  except ValueError:
    break

此代码然后进入无限循环。

我知道有变通办法,事实上我已经实施了一个。根据文档,我只想知道为什么队列没有像预期的那样引发 ValueError

澄清一下,我的理解是,只要队列关闭并调用 .get 就会引发错误。

我看到有人建议将超时设置为 1 并在队列为空时中断,但是:

def func(q):
  for i in range(10):
    time.sleep(10)
    q.put(i)

如果我们在队列为空时中断会导致代码过早退出

3 个答案:

答案 0 :(得分:0)

<块引用>

如果 timeout 是一个正数,它最多会阻塞 timeout 秒,如果在那段时间内没有可用的项目,则会引发 Queue.Empty 异常。

while True 是一个无限循环,如果你只是给 queue.Empty 一个通行证。

import multiprocessing
import queue

def func(a,b):
    print('func acquired {}\t{}'.format(a,b))

q = multiprocessing.Queue()
p=multiprocessing.Process(target=func,args=(range(5),q))
p.start()
while True:
  try:
    q.get(timeout=1)
  except queue.Empty:
    print("Empty")
    break
  except ValueError:
    break
print('termination')

输出:

func acquired range(0, 5)       <multiprocessing.queues.Queue object at 0x7f42d0989710>
Empty
termination

答案 1 :(得分:0)

首先你们都使用 #selector(resignFirstResponder) 作为变量名,所以异常将处理 queue 第二次使用 queue.Empty for while 循环停止

break

如文档所说,如果您提供 q = multiprocessing.Queue() p=multiprocessing.Process(target=func,args=(range(5),q)) p.start() while True: try: q.get(timeout=1) except queue.Empty: print("Empty") break except ValueError: break true 和 block none,则此操作将进入对底层锁的不间断等待。 Doc

答案 2 :(得分:0)

我想通了!

关闭队列只会将放入队列的对象刷新到调用 close() 的线程。其他线程不受影响,即使在当前线程上关闭,东西仍然可以放入队列。