Python队列(queue)

Python队列(queue)教程

Python 的队列(queue)可以理解为一个容器,这个容器里面存放的就是数据,Python 队列也就是 queue 是 Python 中的标准库,可以直接 import 引用,在 Python2.x 中,模块名为 Queue。

Python队列(queue)作用

在 Python 中,多个 线程 之间的数据是共享的,多个线程进行数据交换的时候,不能够保证数据的安全性和一致性,此时我们可以使用 互斥锁 或者 递归锁 来保证数据的一致性。

除了使用互斥锁和递归锁,Python 还为我们提供了队列来解决此问题,队列可以完美解决线程间的数据交换,保证线程间数据的安全性和一致性。

Python队列(queue)与列表的区别

队列是一只数据结构,数据存放方式类似于 列表,但是取数据的方式不同于列表。队列的数据有三种方式:

  • 先进先出(FIFO),即哪个数据先存入,取数据的时候先取哪个数据,同生活中的排队买东西。
  • 先进后出(LIFO),同栈,即哪个数据最后存入的,取数据的时候先取,同生活中手枪的弹夹,子弹最后放入的先打出。
  • 优先级队列,即存入数据时候加入一个优先级,取数据的时候优先级最高的取出。
  • 列表中取数据,相当于复制一份数据,而队列中,数据只有一份,取走了就没了。

Python队列(queue)常用方法

函数 说明
queue.qsize() 返回队列的大小
queue.empty() 如果队列为空,返回True,反之False
queue.full() 如果队列满了,返回True,反之False
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() 在完成一项工作之后,queue.task_done()函数向任务已经完成的队列发送一个信号
queue.join() 实际上意味着等到队列为空,再执行别的操作

案例

使用队列实现先进先出

使用 Python Queue 实现队列的先进先出

import queue import threading import time que = queue.Queue(2) #加数字限制队列的长度,最多能够存入2个数据,有取出才能继续存入 def put(): for i in range(3): #顺序存入数字 0 到 2 print("Put Data =", i, end=', ') que.put(i) time.sleep(1) #延迟存入数字,当队列中没有数据的时候,get函数取数据的时候会阻塞,直到有数据存入后才从阻塞状态释放取出新数据 def get(): for i in range(3): #从第一个数字0开始取,直到 2 print("Get Data =", que.get()) if __name__ == '__main__': print("嗨客网(www.haicoder.net)") t1 = threading.Thread(target=put, args=()) t1.start() t2 = threading.Thread(target=get, args=()) t2.start()

程序运行后,控制台输出如下:

19 python队列queue.png

我们首先使用 queue.Queue 创建了一个大小为 2 的队列 que,接着,我们创建了两个线程,即 put 和 get,其中 put 负责向队列写入数据, get 负责从队列获取数据。

从运行结果,我们发现,每次写入一个数据到队列,我们都可以从队列获取到一个数据,而且写入的数据被取出之后,该数据就不会再存在队列中了。

使用 join 阻塞

使用 join 阻塞和 task_done 信号模拟先进先出队列

import queue import threading import time que = queue.Queue(2) #加数字限制长度 def put(): for i in range(3): print("put data =", i) time.sleep(1) que.put(i) que.join() # 阻塞进程 print("put data done") def get(): for i in range(3): print("get data =", que.get()) que.task_done() # 必须每取走一个数据,发一个信号给join if __name__ == '__main__': print("嗨客网(www.haicoder.net)") t1 = threading.Thread(target=put, args=()) t1.start() t2 = threading.Thread(target=get, args=()) t2.start()

程序运行后,控制台输出如下:

20 python队列queue.png

我们首先使用 queue.Queue 创建了一个大小为 2 的队列 que,接着,我们创建了两个线程,即 put 和 get,其中 put 负责向队列写入数据, get 负责从队列获取数据。

从运行结果,我们发现,每次写入一个数据到队列,我们都可以从队列获取到一个数据,并且拿走数据之前,数据是无法再次写入队列的。

因为在线程处理函数 put 中,我们每次写入一个数据都会使用 que.join() 来阻塞当前线程,直到线程处理函数 get 获取完数据发送一个 que.task_done() 此时 put 函数的阻塞才会被终止,才可以继续下一次的数据的写入。

Python队列(queue)教程总结

Python 的队列(queue)可以理解为一个容器,这个容器里面存放的就是数据,Python 队列也就是 queue 是 Python 中的标准库,可以直接 import 引用,在 Python2.x 中,模块名为 Queue。

Python队列(queue)与列表的区别,队列是一只数据结构,数据存放方式类似于列表,但是取数据的方式不同于列表。队列的数据有三种方式:

  • 先进先出(FIFO),即哪个数据先存入,取数据的时候先取哪个数据,同生活中的排队买东西。
  • 先进后出(LIFO),同栈,即哪个数据最后存入的,取数据的时候先取,同生活中手枪的弹夹,子弹最后放入的先打出。
  • 优先级队列,即存入数据时候加入一个优先级,取数据的时候优先级最高的取出。
  • 列表中取数据,相当于复制一份数据,而队列中,数据只有一份,取走了就没了。