queue 模块下提供了几个阻塞队列,这些队列主要用于实现线程通信。在 queue 模块下主要提供了三个类,分别代表三种队列,它们的主要区别就在于进队列、出队列的不同。

关于这三个队列类的简单介绍如下:

queue.Queue(maxsize=0):代表 FIFO(先进先出)的常规队列,maxsize 可以限制队列的大小。如果队列的大小达到队列的上限,就会加锁,再次加入元素时就会被阻塞,直到队列中的元素被消费。如果将 maxsize 设置为 0 或负数,则该队列的大小就是无限制的。

queue.LifoQueue(maxsize=0):代表 LIFO(后进先出)的队列,与 Queue 的区别就是出队列的顺序不同。

PriorityQueue(maxsize=0):代表优先级队列,优先级最小的元素先出队列。

这三个队列类的属性和方法基本相同, 它们都提供了如下属性和方法:

Queue.qsize():返回队列的实际大小,也就是该队列中包含几个元素。

Queue.empty():判断队列是否为空。

Queue.full():判断队列是否已满。

Queue.put(item, block=True, timeout=None):向队列中放入元素。如果队列己满,且 block 参数为 True(阻塞),当前线程被阻塞,timeout 指定阻塞时间,如果将 timeout 设置为 None,则代表一直阻塞,直到该队列的元素被消费;如果队列己满,且 block 参数为 False(不阻塞),则直接引发 queue.FULL 异常。

Queue.put_nowait(item):向队列中放入元素,不阻塞。相当于在上一个方法中将 block 参数设置为 False。

Queue.get(item, block=True, timeout=None):从队列中取出元素(消费元素)。如果队列已满,且 block 参数为 True(阻塞),当前线程被阻塞,timeout 指定阻塞时间,如果将 timeout 设置为 None,则代表一直阻塞,直到有元素被放入队列中; 如果队列己空,且 block 参数为 False(不阻塞),则直接引发 queue.EMPTY 异常。

Queue.get_nowait(item):从队列中取出元素,不阻塞。相当于在上一个方法中将 block 参数设置为 False。

下面以普通的 Queue 为例介绍阻塞队列的功能和用法。首先用一个最简单的程序来测试 Queue 的 put() 和 get() 方法。

import queue

# 定义一个长度为2的阻塞队列

bq = queue.Queue(2)

bq.put("Python")

bq.put("Python")

print("1111111111")

bq.put("Python") # ① 阻塞线程

print("2222222222")

上面程序先定义了一个大小为 2 的 Queue,程序先向该队列中放入两个元素,此时队列还没有满,两个元素都可以被放入。当程序试图放入第三个元素时,如果使用 put() 方法尝试放入元素将会阻塞线程,如上面程序中 ① 号代码所示。

与此类似的是,在 Queue 已空的情况下,程序使用 get() 方法尝试取出元素将会阻塞线程。

在掌握了 Queue 阻塞队列的特性之后,在下面程序中就可以利用 Queue 来实现线程通信了。

import threading

import time

import queue

def product(bq):

str_tuple = ("Python", "Kotlin", "Swift")

for i in range(99999):

print(threading.current_thread().name + "生产者准备生产元组元素!")

time.sleep(0.2);

# 尝试放入元素,如果队列已满,则线程被阻塞

bq.put(str_tuple[i % 3])

print(threading.current_thread().name \

+ "生产者生产元组元素完成!")

def consume(bq):

while True:

print(threading.current_thread().name + "消费者准备消费元组元素!")

time.sleep(0.2)

# 尝试取出元素,如果队列已空,则线程被阻塞

t = bq.get()

print(threading.current_thread().name \

+ "消费者消费[ %s ]元素完成!" % t)

# 创建一个容量为1的Queue

bq = queue.Queue(maxsize=1)

# 启动3个生产者线程

threading.Thread(target=product, args=(bq, )).start()

threading.Thread(target=product, args=(bq, )).start()

threading.Thread(target=product, args=(bq, )).start()

# 启动一个消费者线程

threading.Thread(target=consume, args=(bq, )).start()

上面程序启动了三个生产者线程向 Queue 队列中放入元素,启动了三个消费者线程从 Queue 队列中取出元素。本程序中 Queue 队列的大小为 1,因此三个生产者线程无法连续放入元素,必须等待消费者线程取出一个元素后,其中的一个生产者线程才能放入一个元素。

运行该程序,将会看到如图 1 所示的结果。

图1 使用 Queue 控制线程通信

从图 1 可以看出,三个生产者线程都想向 Queue 中放入元素,但只要其中一个生产者线程向该队列中放入元素之后,其他生产者线程就必须等待,等待消费者线程取出 Queue 队列中的元素。

python 队列实现_Python Queue队列实现线程通信相关推荐

  1. python queue 查询是否在队列中_Python queue队列

    Queue Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递 基本FIFO队列 clas ...

  2. python 优先队列_Python Queue队列实现线程通信

    queue 模块下提供了几个阻塞队列,这些队列主要用于实现线程通信.在 queue 模块下主要提供了三个类,分别代表三种队列,它们的主要区别就在于进队列.出队列的不同.关于这三个队列类的简单介绍如下: ...

  3. python队列效率_Python之队列Queue

    今天我们来了解一下python的队列(Queue) queue is especiall useful in threaded programming when information must be ...

  4. python 消息机制_Python并发编程之线程消息通信机制任务协调(四)

    . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程无非就是创建一下,然后再start()下,实在是太简单了. 可是要知道,在真实的项目中,实际场景可要我们举 ...

  5. python apply_async死锁_python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是不 ...

  6. python 消息队列 get是从队首还是队尾取东西_Python -- queue队列模块

    import Queue myqueue = Queue.Queue(maxsize = 10) Queue.Queue类即是一个队列的同步实现.队列长度可为无限或者有限.可通过Queue的构造函数的 ...

  7. java map 队列_Java:queue队列,map集合

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List.Set同一级别,都是继承了Collection接口.Lin ...

  8. python 网络连接_python网络连接之tcp通信

    #encoding=utf-8 # 创建一个 TCP 服务器程序,这个程序会把客户发送过来的字 # 符串加上一个时间戳(格式:'[时间]数据')返回给客户. from socket import * ...

  9. 两种方式实现线程通信:三个线程交替打印AABBCC

    多线程之间是抢占资源的,使用线程通信可以达到线程按序执行的目的 线程共享资源类, 首先创建一个资源类, 包含三个打印的方法以及首次打印的字符串 多个线程访问,方法加synchronized同步锁 cl ...

最新文章

  1. ndarray维度认识及np.concatenate函数详解
  2. tensorflow1.0代码迁移到2.0官方指导
  3. aspose.word在某个字后面自动换行_在Arctime里制作字幕如何自动换行?如何添加注释、广告语?...
  4. 信用评分卡模型开发及评估指标
  5. 线性代数可以速成吗_怎么在一个晚上搞定线性代数?
  6. python怎么将if和try一起用_Python使用try/catch还if效率更高一些?
  7. java调用gbase存储过程,GBase 8T数据库存储过程使用出参示例
  8. duration java_Java Duration类| toMinutes()方法与示例
  9. 大势所趋与各具特色 超融合市场玩家大盘点
  10. 韩山师范计算机科学与技术,韩山师范学院计算机科学与技术专业
  11. 【知识图谱】BERT meet KG 第二弹:新训练方式,新问题视角
  12. 软件设计精要与模式(第2版)
  13. 雨夜深思——开发平台(二)
  14. mysql left outer join_关于mysql中的left join和left outer join的区别
  15. h5学习笔记:rem单位在一些安卓机计算异常
  16. matlab交大校歌,骊歌轻扬,共待来日——毕业之际,交大校歌唱与你听!
  17. 口令不符合oracle建议标准,INS-30011 输入的ADMIN口令不符合Oracle建议的标准
  18. 百度,你能不能有点节操?
  19. atan2与atan的区别
  20. 情感驿站 | 如何构建自己的知识体系?

热门文章

  1. 最全干货回顾,一文看尽亚马逊 re:Invent 2020全貌
  2. 开源数据库再创里程碑,PingCAP 获 2.7 亿美元融资
  3. 80% 的学校还在给新生上 C 语言,它们 OUT 了吗?
  4. Get!读懂数据科学和机器学习,看这文就够了!
  5. 联合国为何 Pick 腾讯?
  6. 区块链数字合约,如何将下放所有权?
  7. 2020 年,程序员如何拥抱 5G ?
  8. 干货满满!全面详解如何用递归解题!
  9. “上云”很 fashion 的今天,GeekPwn 搞了个比赛……
  10. 谁说 C++ 的强制类型转换很难懂?