Python - 队列的工作原理是什么?

3
关于文档中的例子: https://docs.python.org/2/library/queue.html#Queue.Queue.get 本例展示了如何使用Python中的Queue模块来实现线程间通信和同步。具体而言,get()方法从队列中获取并返回一个元素,如果队列为空,则阻塞调用直到有可用元素。
def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

工作人员如何知道所有的工作都已完成,队列为空,我们可以退出呢?我不理解...


你现在学习Python吗?请确保使用Python 3 :) (https://docs.python.org/3.7/library/queue.html#Queue.Queue.get) - hellow
实际上我需要它在RHEL6上运行 - 这意味着Python 2.6。有点可怕。;) - Maciej Wawrzyńczuk
2个回答

3
您的工作程序运行在一个while True:循环中,这意味着该函数/线程将永远不会返回。
“神奇”的地方在于您没有显示的代码:
 t = Thread(target=worker)
 t.daemon = True
 t.start()

Daemon参数控制上层线程何时可以退出。

当没有非守护进程的活动线程时,整个Python程序就会退出。

这意味着程序将会退出,因为主线程已经退出。工作线程仍然存在,但是当主线程结束时(因为“没有非守护线程了”),它将被销毁。

主线程退出条件为:

q.join()
< p >当 join 停止阻塞执行时,它的文档将显示。

当未完成任务的数量降至零时,join() 就会解除阻塞。


1
@MaciejWawrzyńczuk 对不起,我想我误读了你的问题。我的编辑解决了吗? - hellow
谢谢,我现在好多了。 :) 但是在程序退出时,我仍然遇到一些奇怪的线程错误。这不是我的最大问题,但我感觉需要学习更多。有关于Python多线程编程的指南/书籍吗?你能推荐一些吗? - Maciej Wawrzyńczuk

1
我会简单地解释一下。队列基本上是像列表一样的项目集合,不同之处在于它不允许随机访问元素。您需要按照特定的方式插入和删除项目。队列的默认类型是FIFO(先进先出)。正如您从名称中可以推断出来的那样,它就像您在任何超市(或任何地方)看到的正常队列,第一个进入排队的人将首先离开。
队列有三种类型:
  1. FIFO
  2. LIFO
  3. PRIORITY
FIFO就像我说的,遵循先进先出的规则:
import queue #importing the library

q=queue.Queue() #create a queue object

for i in range(5):
    print(q.put(i)) #adding elements into our queue

while not q.empty():
    print(q.get()) #to delete item and printing it

LIFO(后进先出)原则是指,最后进入的元素首先被处理:
import queue #importing the library

q=queue.LifoQueue() #create a queue object

for i in range(5):
    print(q.put(i)) #adding elements into our queue

while not q.empty():
    print(q.get()) #to delete item and printing it

优先队列按升序输出数据,也就是最小的元素会先退出队列。

import queue #importing the library

q=queue.LifoQueue() #create a queue object


q.put(3) 
q.put(7) 
q.put(2) 
q.put(7) 
q.put(1) 


while not q.empty():
    print(q.get()) #to delete item and printing it

回答你的最后一个问题,正如你在示例中所看到的,你可以使用q.empty()来检查你的队列是否为空。

如果你还有任何疑问,请随时提出。


抱歉,但是您的回答完全没有回答问题,或者我错了吗? - hellow
感谢提供全面的指南。 - Maciej Wawrzyńczuk
1
@hellow 你说得没错。但既然你用代码回答了他的疑问,我想他可能会对理解队列感兴趣,因为他从分享的链接中很难理解它。 - isrj5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接