Python3队列:什么时候阻塞等待没有超时返回无?

时间:2017-05-03 11:01:14

标签: python multithreading python-3.x queue

我想知道python3队列上没有超时的阻塞获取什么时候可以返回None。

python3 queue documentation声明:

  

Queue.get(block = True,timeout = None)

     

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

对我来说,这意味着没有参数的get()将等待队列中的元素并仅返回,因此总是会返回一个非None的值。仍然在queue documentation底部的示例中,给出了以下代码:

while True:
    item = q.get()
    if item is None:
        break
    ...

对项目的显式检查为None意味着可以返回None。在哪种情况下会发生这种情况?

1 个答案:

答案 0 :(得分:0)

通常,以干净的方式正确地结束线程在多线程程序中是一个非常重要的问题。

当线程之间的主要通信通道是一个队列时,消费线程通常会在调用get()时阻塞该队列,一个好的技术是使用一个通常不会作为数据发出的值来表示没有更多的数据将被排队并且消费者线程应该退出。

制作人主题:

with open('/run/myapp/datapipe', 'r') as f:
    for line in f:
        queue.put(line)

# signal end of communication with a sentinel value of None
queue.put(None)

# further clean up

消费者主题:

while True:
    line = queue.get()
    if line is None:
        # if sentinel value was found, break and clean up
        queue.task_done()
        break

    # process line here
    queue.task_done()

# clean up

如果None可以作为普通数据流的一部分出现,您还可以提供另一个合适的值作为通信标记的结尾。

此外,如果您有多个消费者线程,这种简单的结束标记排队技术就不够了,因为只有一个线程会使标记出列。在这种情况下,您可以在获取标记后将每个使用者线程put()作为标记返回到队列中,从而将结束标记一个接一个地交给每个使用者线程。