7、生产者消费者模型(*****)(思聪吃热狗代码)
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。
该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。
在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,
那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,
如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。
为了解决这个问题于是引入了生产者和消费者模式。
1、什么是生产者消费者模型?
模型 设计模式 三层结构 等等表示的都是一种编程思路
模型指的是解决问题的一种思路
实现生产者消费者模型三要素
1、生产者:生产数据的任务
2、消费者:处理数据的任务
3、队列Queue:一个共享的数据容器
如何实现:
生产者<-->队列<——>消费者
(比如: 文件夹里有十个文本文档 要求你找出文件中包含习大大关键字的文件
打开并读取文件数据就是生产者
查找关键字的过程就是消费者)
2、什么时候用生产者消费者模型?
在程序中有明显地两类任务,一类负责生产数据,另外一个类则拿到生产的数据进行处理,此时就应该
考虑使用生产者消费者模型来处理这种问题
3、为什么要用生产者消费者模型?好处,能解决的问题是?
1、平衡生产者与消费者之间的工作能力,从而提高程序整体处理数据的速度
2、将生产者与消费者 解耦和
原理:
解耦和指的是生产者不与消费者直接打交道,
生产者可以不停地往队里里放数据
消费者可以不停地从队列里取走数据进行处理
生产者消费者模型案例:制作热狗
# 方法一:
from multiprocessing import Process,Queue
def make_hotdog(queue,name):
queue.put(data)
def eat_hotdog(queue,name):
data = queue.get()
if __name__ == '__main__':#创建队列
q = Queue()
p1 = Process(target=make_hotdog,args=(q,"邵钻钻的热狗店"))
c1 = Process(target=eat_hotdog, args=(q,"思聪"))
p1.start()
c1.start()
p1.join() # 让主进程等三家店全都做完后....
q.put(None) #发送结束信号,有几个消费者,就放几行None
# 方法二:
from multiprocessing import Process,JoinableQueue
def make_hotdog(queue,name):
queue.put(data)
q.join()
def eat_hotdog(queue,name):
data = queue.get()
queue.task_done()
if __name__ == '__main__':#创建队列
q = JoinableQueue()
p1 = Process(target=make_hotdog,args=(q,"邵钻钻的热狗店"))
c1 = Process(target=eat_hotdog, args=(q,"思聪"))
p1.start()
c1.daemon = True# 将消费者作为主进程的守护进程
c1.start()
p1.join() # 让主进程等三家店全都做完后....
线程 (生产者消费者代码 抢票代码)
1、线程理论(*****)
1 线程指的是一条流水线的工作过程 线程是CPU的基本执行单位,一个进程必须有至少一个线程
线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程
车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线
流水线的工作需要电源,电源就相当于cpu
所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),
而线程才是cpu上的执行单位。
为什么用?
需要实现并发执行任务
2、线程vs进程
1.资源开销 进程开销大 线程开销小(在多线程中CPU的切换速度会非常快 但资源消耗没有进程高)
如果我们的软件是一个工厂,该工厂有多条流水线,流水线工作需要电源,电源只有一个即cpu(单核cpu)
一个车间就是一个进程,一个车间至少一条流水线(一个进程至少一个线程)
创建一个进程,就是创建一个车间(申请空间,在该空间内建至少一条流水线)
而建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小
2.数据共享 一个进程内的所有线程数据共享,不同进程内资源隔离
2、开启线程的两种方式(*****)
1.实例化Thread类 参数target中传入任务函数
2.继承Thread类 实现run函数
from threading import Thread
3、守护进程vs守护线程(**)
大前提:一个任务守护另外一个任务代码的执行过程
在一个进程内只有一个线程的情况下,守护进程会在主进程代码执行完毕后立刻结束
在一个进程可以开启多个线程,守护的线程会在该进程内所有非守护线程都执行完毕后才结束
主进程代码运行完毕,守护进程就会结束
a 守护 b 同时还有另一个线程 c
a 会等到 b 和 c都结束才结束
皇后 守护皇帝
皇宫里还有太子
皇后会等到皇帝和太子都死了 才死
守护线程会等待所有非守护线程结束后才算结束
main
sub1
sub2
sub3
sub1.deamon = True
sub1会等待 main sub2 sub3 全都结束 才会结束