Python公开课 - 标准库queue基本使用

前言

在python中,多个线程之间的数据是共享的,多个线程进行数据交换的时候,不能够保证数据的安全性和一致性,所以当多个线程需要进行数据交换的时候,队列就出现了,队列可以完美解决线程间的数据交换,保证线程间数据的安全性和一致性。

基本介绍

Python标准库中的queue模块实现了多生产者,多消费者队列。

当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。Queue模块中的类实现了所有必需的锁定语义。

这取决于Python中线程支持的可用性; 看threading 模块。

该模块实现了三种类型的队列,它们的区别仅在于取条目的顺序。

  • FIFO 队列,即先进先出队列,添加的第一个条目是第一个取出的条目
  • LIFO队列中,最近添加的条目是第一个取出的(像堆栈一样运行)
  • 使用优先级队列,条目将保持排序(使用heapq模块),并首先检索最低值的条目

构造三种队列

在Python中,可以通过以下方式构造上述三种队列

  1. Python queue模块的FIFO队列先进先出。 class queue.Queue(maxsize)
  2. LIFO类似于堆,即先进后出。 class queue.LifoQueue(maxsize)
  3. 优先级队列级别越低越先出来。 class queue.PriorityQueue(maxsize)

queue模块中的常用方法

  • queue.qsize() 返回队列的大致大小,并非精准
  • queue.empty() 如果队列为空,返回True,反之False
  • queue.full() 如果队列满了,返回True,反之False,注意queue.full 与 maxsize 大小对应
  • queue.get([block[, timeout]])获取队列,timeout等待时间
  • queue.get_nowait() 相当queue.get(False)
  • queue.put(item) 将条目写入队列,timeout等待时间
  • queue.put_nowait(item) 相当queue.put(item, False)
  • queue.task_done() 表示以前排队的任务已完成。由队列使用者线程使用。对于每个get()用于获取任务的人,后续调用 task_done()告诉队列任务的当前条目处理完成。
  • queue.join() 实际上意味着等到队列为空,再执行别的操作

示例说明

import queue
import threading

def worker():
    while True:
        item = q.get()
        if item is None:
            break
        #do_work(item)
        print(item)
        q.task_done()

num_worker_threads=3
q = queue.Queue()
threads = []
for i in range(num_worker_threads):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)

for item in range(10):
    q.put(item)

# block until all tasks are done
print ('wating_process')
q.join()
print ('queue_done')

# stop workers
for i in range(num_worker_threads):
    q.put(None)
for t in threads:
    t.join()
print ('exit')
展开剩余53%