进程Queue、线程Queue、堆栈、生产者消费者模型
没学队列之前,可以用文件实现进程之间通信
但是有2个问题:
1. 速度慢:文件是保存在硬盘空间
2. 为了数据安全要加锁(处理锁是一件很麻烦的事,容易死锁,建议自己轻易不要处理锁)
队列:队列是基于管道加锁实现的
进程Queue
进程队列:
from multiprocessing import Queue q = Queue(3)
q.put([1,2])
q.put('a')
q.put(1) print(q.get())
print(q.get())
print(q.get())
##
# [1, 2]
# a
#
取值的过程中,可能发生夯住的情况
程序卡住1:取的比放进去的多
from multiprocessing import Queue q = Queue(3)
q.put(1) print(q.get())
print(q.get()) # 放了1个,取了2次(第二次管道空了,就是取空),第2次程序卡住了(锁住了)
程序卡住2:放进去的比管道设置的多
from multiprocessing import Queue q = Queue(3)
q.put(1)
q.put(2)
q.put(2)
q.put(4) #设置管道为3,放进去4个,程序卡住了(锁住了) print(q.get())
print(q.get())
总之:取的次数不能超过放进去的次数,放进去的次数不能超过管道设置的次数
q = Queue( )
可以不设置大小,但是内存不是无限大的
不可以放大的数据(比如一个视频)(可以放一个视频连接)
线程Queue
线程队列:
import queue q = queue.Queue(3)
q.put(1)
q.put(2) print(q.get())
print(q.get()) #
#
线程--堆栈
队列:先进先出
堆栈:后进先出
import queue q = queue.LifoQueue(3)
q.put(1)
q.put(2)
q.put(3) print(q.get())
print(q.get())
print(q.get()) #
#
#
优先级队列
import queue q = queue.PriorityQueue(3)
q.put((2,'a')) #参数是一个元组,元组的第一个元素是一个数字,数字越小,优先级越高
q.put((-2,'b'))
q.put((0,'c')) print(q.get())
print(q.get())
print(q.get()) # (-2, 'b')
# (0, 'c')
# (2, 'a')
生产者和消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
如果只产生数据,不处理数据,就不需要用这个模型。
示例:
生产者和消费者中间加个队列,结耦
生产者和队列 消费者和队列
生产者产生的数据放进队列里面,消费者处理数据就从队列里面拿值
import time, os
from multiprocessing import Process, Queue def task(q):
for i in range(10):
res = '第%s个包子' % (i + 1)
time.sleep(0.2)
q.put(res)
print('%s生产了%s' % (os.getpid(),res)) def eat(q):
while True:
res = q.get()
if res is None:
break
time.sleep(0.5)
print('路人甲吃了%s' % res) if __name__ == '__main__':
q = Queue()
p1 = Process(target=task, args=(q,))
p2 = Process(target=eat, args=(q,))
p1.start()
p2.start()
p1.join()
q.put(None) #######
768生产了第1个包子
768生产了第2个包子
768生产了第3个包子
路人甲吃了第1个包子
768生产了第4个包子
768生产了第5个包子
768生产了第6个包子
路人甲吃了第2个包子
768生产了第7个包子
768生产了第8个包子
路人甲吃了第3个包子
768生产了第9个包子
768生产了第10个包子
路人甲吃了第4个包子
路人甲吃了第5个包子
路人甲吃了第6个包子
路人甲吃了第7个包子
路人甲吃了第8个包子
路人甲吃了第9个包子
路人甲吃了第10个包子
Queue是生产者给消费者发送信号
JoinableQueue 消费者给生产者发送信号
import time, os
from multiprocessing import Process, JoinableQueue def task(q):
for i in range(3):
res = '第%s个包子' % (i + 1)
time.sleep(0.2)
q.put(res)
print('%s生产了%s' % (os.getpid(), res))
q.join() #生产者生产完数据后,查看一共接收了多少个信号,如果信号数量<放进去的数据量,等待;当信号数=放进去的数据数 时,生产者执行完毕(两个数量相等,也说明了处理数据的消费者也把数据处理完了,也需要关闭了)(放在循环外面)
#生产者结束: 消费者确实把所有数据都收到 def eat(q):
while True:
res = q.get()
time.sleep(0.5)
print('%s吃了%s' % (os.getpid(), res))
q.task_done() #消费者每次拿一个值,就给生产者发送一个信号(放在循环里面,且把数据处理完之后再发送) if __name__ == '__main__':
q = JoinableQueue()
p = Process(target=task, args=(q,))
c = Process(target=eat, args=(q,))
c.daemon = True #之所以要把消费者变成守护,是因为生产者可以得到信号,自己结束,但消费者不知道什么时候结束,就会一直等待(从队列取空),变成守护后,下面的p.join()结束后,代表主进程结束,数据处理完了,消费者没必要存在了,正好主进程强制把守护关闭
p.start()
c.start()
p.join() #等待生产者结束的目的就是关闭守护(消费者没必要存在了)
进程Queue、线程Queue、堆栈、生产者消费者模型的更多相关文章
- Python守护进程、进程互斥锁、进程间通信ICP(Queue队列)、生产者消费者模型
知识点一:守护进程 守护进程:p1.daemon=True 守护进程其实就是一个“子进程“,守护=>伴随 守护进程会伴随主进程的代码运行完毕后而死掉 进程:当父进程需要将一个任务并发出去执行,需 ...
- 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)
参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...
- 线程锁、threading.local(flask源码中用的到)、线程池、生产者消费者模型
一.线程锁 线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue 线程不安全 + 人(锁) => 排队处理 1.RLock/Lock:一次放一个 a.创建10个线 ...
- 网络编程基础----并发编程 ---守护进程----同步锁 lock-----IPC机制----生产者消费者模型
1 守护进程: 主进程 创建 守护进程 辅助主进程的运行 设置进程的 daemon属性 p1.daemon=True 1 守护进程会在主进程代码执行结束后就终止: 2 守护进程内无法再开启子进程 ...
- 锁丶threading.local丶线程池丶生产者消费者模型
一丶锁 线程安全: 线程安全能够保证多个线程同时执行时程序依旧运行正确, 而且要保证对于共享的数据,可以由多个线程存取,但是同一时刻只能有一个线程进行存取. import threading v = ...
- java多线程:线程间通信——生产者消费者模型
一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是,多个线程之间如何协作呢? 我们看一个仓库 ...
- 基于线程实现的生产者消费者模型(Object.wait(),Object.notify()方法)
需求背景 利用线程来模拟生产者和消费者模型 系统建模 这个系统涉及到三个角色,生产者,消费者,任务队列,三个角色之间的关系非常简单,生产者和消费者拥有一个任务队列的引用,生产者负责往队列中放置对象(i ...
- 进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型
一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: import param ...
- python2.0_s12_day9之day8遗留知识(queue队列&生产者消费者模型)
4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 * 6.queue队列 * 7.生产者消费者模型 4.6 queue队列 que ...
- 使用队列queue实现一个简单的生产者消费者模型
一.生产者消费者模型 我们去超市商店等地购买商品时,我们大部分人都会说自己是消费者,而超市的各大供货商.工厂等,自然而然地也就成了我们的生产者.如此一来,生产者有了,消费者也有了,那么将二者联系起来的 ...
随机推荐
- iOS 利用UIWebView与JavaScript交互的最简单办法
这里说的是针对iOS的!并且方法很简单!!并且验证可行的!!! 1, UIWebView调用 JavaScript 的函数: NSString* strValue = [webView stringB ...
- Bootstrap学习笔记之Nestable可拖拽树结构
Nestable是基于Bootstrap的一个可拖拽的树结构表现插件. 下面粗略的介绍一下它的用法,只作为学习参考,如有不合适之处,请各位凑合看. 下图是我在现在系统中用到的Nestable,对系统模 ...
- Dreamoon and MRT
Dreamoon and MRT 题目链接: http://codeforces.com/group/gRkn7bDfsN/contest/212299/problem/B 只需要考虑相对位置,设a0 ...
- js 时间戳 随机数 new Date().getTime()
一:时间转时间戳:javascript获得时间戳的方法有四种,都是通过实例化时间对象 new Date() 来进一步获取当前的时间戳 1.var timestamp1 = Date.parse(new ...
- 枚举 || CodeForces 742B Arpa’s obvious problem and Mehrdad’s terrible solution
给出N*M矩阵,对于该矩阵有两种操作: 1.交换两列,对于整个矩阵只能操作一次 2.每行交换两个数. 交换后是否可以使每行都递增. *解法:N与M均为20,直接枚举所有可能的交换结果,进行判断 每次枚 ...
- 《3+1团队》【Alpha】Scrum meeting 5
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 3+1团队 团队博客地址 https://home.cnblogs.com/u/3-1group ...
- packet capture
1.下载地址:https://www.coolapk.com/apk/app.greyshirts.sslcapture
- ZOJ3228 Searching the String (AC自动机)
Searching the String Time Limit: 7 Seconds Memory Limit: 129872 ...
- Redis进阶例子
工作中用到的RabbitMQ例子 , 但是最后没有用 , 用的CMQ , 顺便说下CMQ社区真的少 , 并且功能少 . 一.消息体 package com.bootdo.common.rabbitmq ...
- 169. Majority Element@python
Given an array of size n, find the majority element. The majority element is the element that appear ...