Python3学习之路~9.4 队列、生产者消费者模型
一 队列queue
当必须在多个线程之间安全地交换信息时,队列在线程编程中特别有用。
队列的作用:1.解耦,使程序直接实现松耦合 2.提高处理效率
列表与队列都是有顺序的,但是他们之间有一个很大的区别:从列表中取出一个数据,数据还在列表中,从队列中取出一个数据,队列中就减少一个数据。class queue.Queue(maxsize=0) #先入先出
- class queue.LifoQueue(maxsize=0) #last in fisrt out
- class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列。
- #maxsize是一个整数,用于设置可以放入队列的数据的上限。达到此大小后,插入将阻止,直到消耗队列项。
- #如果maxsize小于或等于零,则队列大小为无限大。
- #PriorityQueue首先检索priority_number最低值的数据(最低值是由sorted(list(entries))[0]返回)。
- #放入PriorityQueue中的数据的典型模式是以下形式的元组:(priority_number,data)。
- exception queue.Empty #在对空队列调用非阻塞的get()或get_nowait()时引发的异常。
- exception queue.Full #在对已满的队列调用非阻塞put()或put_nowait()时引发的异常。
- Queue.qsize() #返回队列长度
- Queue.empty() #如果队列为空,返回True
- Queue.full() #如果队列已满,返回True
- Queue.put(item, block=True, timeout=None)
- #将数据放入队列。如果block=True且timeout=None(默认值),则在必要时(队列满时进行put操作)阻塞,直到队列有空闲可用。
- #若timeout=正数,它会阻塞最多超时秒,如果在该时间内队列没有空闲可用,则会引发Full异常。
- #若block=False,则在必要时直接抛出Full异常(在这种情况下忽略超时)。
- Queue.put_nowait(item) #相当于put(item, False)
- Queue.get(block=True, timeout=None)
- #从队列中取出一个数据。如果block=True且timeout=None(默认值),则在必要时(队列空时进行get操作)阻塞,直到队列有数据可取。
- #若timeout=正数,它会阻塞最多超时秒,如果在该时间内队列没有数据可取,则会引发Empty异常。
- #若block=False,则在必要时直接抛出Empty异常(在这种情况下忽略超时)。
- Queue.get_nowait() #相当于get(False)
- #Two methods are offered to support tracking whether enqueued tasks have been fully processed by daemon consumer threads.
- Queue.task_done()
- #Indicate that a formerly enqueued task is complete. Used by queue consumer threads.
#For each get() used to fetch a task, a subsequent call to task_done() tells the queue that the processing on the task is complete.- #If a join() is currently blocking, it will resume when all items have been processed (meaning that a task_done() call
#was received for every item that had been put() into the queue).- #Raises a ValueError if called more times than there were items placed in the queue.
- Queue.join() #block直到queue被消费完毕
queue简单操作
- C:\Users\Administrator>python3
- Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD6
- 4)] on win32
- Type "help", "copyright", "credits" or "license" for more information.
- >>> import queue
- >>> q = queue.Queue() #实例化一个队列
- >>> q.put("d1") #放入d1
- >>> q.put("d2") #放入d2
- >>> q.put("d3") #放入d3
- >>> q.get() #不能指定取出哪个数据,必须按照先入先出规则
- 'd1'
- >>> q.get()
- 'd2'
- >>> q.get()
- 'd3'
- >>> q.get() #当队列中没数据可取时,会卡住,无限等待
- #如果不想卡住,可在get之前通过q.qsize()来判断队列长度,或者通过q.get_nowait()来抓住异常
- >>> q.qsize()
- 0
- >>> q.get_nowait()
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "D:\software\Python3.6.5\lib\queue.py", line 192, in get_nowait
- return self.get(block=False)
- File "D:\software\Python3.6.5\lib\queue.py", line 161, in get
- raise Empty
- queue.Empty
- #Queue.get(block=True, timeout=None)方法默认有2个参数,可以手动改掉,使当队列为空时,不卡住。
- >>> q.get(block=False) #当队列为空时,不卡住,直接报异常
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "D:\software\Python3.6.5\lib\queue.py", line 161, in get
- raise Empty
- queue.Empty
- >>> q.get(timeout=1) #当队列为空时,卡住1秒,然后报异常
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "D:\software\Python3.6.5\lib\queue.py", line 172, in get
- raise Empty
- queue.Empty
- >>> import queue
- >>> q = queue.Queue(maxsize=3) #可以设置队列长度最大为3
- >>> q.put(1)
- >>> q.put(2)
- >>> q.put(3)
- >>> q.put(4) #卡住,等待另一个线程把1取出来,4才能放进去
- #Queue.put(item, block=True, timeout=None),法默认有2个参数,可以手动改掉,使当队列满时,不卡住。与get类似
- >>> q.put(4,block=False)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "D:\software\Python3.6.5\lib\queue.py", line 130, in put
- raise Full
- queue.Full
- >>> q.put(4,timeout=1)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "D:\software\Python3.6.5\lib\queue.py", line 141, in put
- raise Full
- queue.Full
- >>> import queue
- >>> q = queue.LifoQueue() #后进先出
- >>> q.put(1)
- >>> q.put(2)
- >>> q.put(3)
- >>> q.get()
- 3
- >>> q.get()
- 2
- >>> q.get()
- 1
- >>> import queue
- >>> q = queue.PriorityQueue() #优先级队列
- >>> q.put((3,"zhao"))
- >>> q.put((10,"qian"))
- >>> q.put((6,"sun"))
- >>> q.put((-1,"li"))
- >>> q.get() #按数字由小到大
- (-1, 'li')
- >>> q.get()
- (3, 'zhao')
- >>> q.get()
- (6, 'sun')
- >>> q.get()
- (10, 'qian')
queue实际操作
二 生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
下面来学习一个最基本的生产者消费者模型的例子
- import threading,queue,time
- q = queue.Queue(maxsize=10)
- def Producer(name):
- count = 0
- while True:
- q.put("小鱼干%s" % count)
- print("[%s]生产了骨头"%name,count)
- count += 1
- time.sleep(0.5)
- def Consumer(name):
- while True:
- print("[%s] 取到[%s]并且吃了它..." %(name,q.get()))
- time.sleep(1)
- for i in range(2):
- p = threading.Thread(target=Producer, args=("主人%s"%i,))
- p.start()
- for i in range(3):
- c = threading.Thread(target=Consumer,args=("大猫%s"%i,))
- c.start()
Python3学习之路~9.4 队列、生产者消费者模型的更多相关文章
- #queue队列 #生产者消费者模型
#queue队列 #生产者消费者模型 #queue队列 #有顺序的容器 #程序解耦 #提高运行效率 #class queue.Queue(maxsize=0) #先入先出 #class queue.L ...
- python2.0_s12_day9之day8遗留知识(queue队列&生产者消费者模型)
4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 * 6.queue队列 * 7.生产者消费者模型 4.6 queue队列 que ...
- Day034--Python--锁, 信号量, 事件, 队列, 生产者消费者模型, joinableQueue
进程同步: 1. 锁 (重点) 锁通常被用来实现对共享资源的同步访问.为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁, ...
- python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))
昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...
- 5 并发编程-(进程)-队列&生产者消费者模型
1.队列的介绍 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的 创建队列的类(底层就是以管道和锁定的方式实现 ...
- python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型
1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...
- 多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现
一.多线程模型一:生产者消费者模型 (1)模型图:(从网上找的图,清晰明了) (2)生产者消费者模型原理说明: 这个模型核心是围绕着一个“仓库”的概念,生产者消费者都是围绕着:“仓库”来进行操作, ...
- 队列&生产者消费者模型
队列 ipc机制:进程通讯 管道:pipe 基于共享的内存空间 队列:pipe+锁 queue from multiprocessing import Process,Queue ### 案例一 q ...
- Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)
Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...
随机推荐
- Java集合 - 明的博客
"In this world there are only two tragedies. One is not getting what one wants, and the other i ...
- unittest(22)- p2p项目实战(3)-project_path
# 3. project_path.py # 用来读取文件的路径 import os # os.path.split(path)使用: # 1.path如果是具体到文件名,则返回最后层级的文件,和文件 ...
- 使用Connector / Python连接MySQL/查询数据
使用Connector / Python连接MySQL connect()构造函数创建到MySQL服务器的连接并返回一个 MySQLConnection对象 在python中有以下几种方法可以连接到M ...
- 你相信吗:一加仑汽油可以给iPhone充电20年
一直以来,苹果公司的iPhone系列手机受到了全世界人民的喜欢,很多人就此成为了果粉.或许是由于我们过于在意iPhone系列手机出彩的外形,所以忽略了很多关于iPhone手机有意思的消息,我们今天就来 ...
- python 堡垒机讲解及实例
paramiko模块,该模块基于SSH用于连接远程服务器并执行相关操作. SSHClient:用于连接远程服务器并执行基本命令 #coding:utf-8 import paramiko ssh=pa ...
- Git学习小结 ~ Lethe's Blog
学习自https://www.liaoxuefeng.com/wiki/896043488029600 一.创建版本库 (1) git init 初始化一个Git仓库 (2)添加文件到Git仓库,分两 ...
- OpenCA搭建
前言: OpenCA是OpenCA开源组织使用Perl对OpenSSL进行二次开发而成的一套完善的PKI免费软件,主要由四部分组成:CA.RA.PUB和NODE.简而言之,PUB是对外提供服务的接口, ...
- 微软手机 能靠Surface Phone卷土重来吗?
能靠Surface Phone卷土重来吗?" title="微软手机 能靠Surface Phone卷土重来吗?"> 就算整体大环境再好,就算是站在风口之上,也总是 ...
- Vue源码之组件化/生命周期(个人向)
大致流程 具体流程 组件化 (createComponent) 构造⼦类构造函数 const baseCtor = context.$options._base // plain options ob ...
- Typora+PicGo+Gitee笔记方案
前言:需要学习的知识太多,从一开始就在寻找一款能让我完全满意的编辑器,然而一直都没有令我满意的.在前两天Typora新版本更新后,总算是拥有了一套我认为很完美的笔记方案:使用Typora编写markd ...