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

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

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

  3. 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 threadingimport timeimport queuedef 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的Queuebq = 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 队列实现_Python Queue队列实现线程通信

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

  2. python 优先队列_python实现最大优先队列 python优先级队列如何最大值优先

    python优先级队列如何最大值优先 啥???????队列默认就有优先级即使告别爱情的时候,也希望你一切都好;小编不再爱你的时候,也许不是小编不爱你,只是,小编已不能再爱你. python3 优先队列 ...

  3. python 优先队列_python中使用优先队列

    相信对于队列的概念大家都不会陌生,这种先入先出的数据结构应用很广泛,像一般的生产消费都会用到队列,关于Queue的用法介绍可以参考我之前的文章 python中的Queue与多进程(multiproce ...

  4. python 优先队列_Python 优先队列

    Python 优先队列,优先队列是一个容器数据结构,使用具有全序关系的键(例如用数值表示的权重)来管理元素,以便快速访问容器中键值最小或最大的元素. 优先队列可被视为队列的改进版,其中元素的顺序不是基 ...

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

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

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

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

  7. python优先队列_python 多线程优先队列Queue详解

    Queue模块允许创建指定长度的队列. 下面是Queue模块的常用方法: get():删除并返回队列中的一个项目 put(): 添加项目到队列 qsize() : 返回队列中元素的个数 empty() ...

  8. python 优先队列_Python中heapq与优先队列【详细】

    本文始发于个人公众号:TechFlow, 原创不易,求个关注 今天的文章来介绍Python当中一个蛮有用的库--heapq. heapq的全写是heap queue,是堆队列的意思.这里的堆和队列都是 ...

  9. 如何使用python多线程_Python:怎样用线程将任务并行化?

    要并行化处理子任务,最简单的方法是为每个子任务创建一个线程去处理.这种方法的缺点是:如果子任务非常多,则需要创建的线程数目会非常多. 并且同时运行的线程数目也会较多.通过使用信号量来限制同时运行的线程 ...

最新文章

  1. 以太网、局域网、互联网区别
  2. 编程一万小时是种什么样的体验?
  3. 从各大跨平台技术说开去,我们真的需要虚拟 DOM 吗?
  4. 调用咏南中间件插件演示
  5. mysql ubuntu 17.04_1、mysql 5.7 ubuntu17.04
  6. day27:三剑客之sed
  7. MTK A/B system说明及配置
  8. 可拖动的进度条_TIM iOS版重大更新:支持语音进度条拖动和暂停
  9. linux常用命令(1)——文件管理
  10. jquery表单美化组件实例
  11. EAS BOS序时簿界面排序
  12. 二维码设备巡检解决方案
  13. DOSBox+MASM,汇编语言环境搭建
  14. 高考证件照要求什么底色
  15. 基于python的批量网页爬虫
  16. 关于最近GD32F103替代STM32F103方案个人记录
  17. 使用苹果MAC电脑怎么旋转图片
  18. DVWA靶机-反射性XSS漏洞(Reflected)
  19. 【UE4】unlua往c++传动态委托参数的方式
  20. jdk 11及以上 javax.annotation.Generated报错 @Generated报错

热门文章

  1. 关于 react的生命周期
  2. Java动态代理实现(转载\整理)
  3. Android APK包文件解析
  4. 华为机试HJ95:人民币转换
  5. linux 重新安装内核,升级操作系统内核(不重新安装UltraPath)
  6. 域做文件服务器,linux 做域文件服务器
  7. linux系统服务器怎么登录日志文件,Linux服务器查看日志的几种方法
  8. python module错误_python 解决方法:ImportError: No module
  9. linux php源码安装mysql_linux源码安装mysql5.7
  10. mac 备份文件 太大 时间机器_新手必看!加速 Mac 时间机器备份速度教程,Time Machine 备份太慢的解决方法...