课程回顾:
并发:在同一个时间段内多个任务同时进行
并行:在同一个事件点上多个任务同时进行
进程的三大基本状态:
就绪状态:所有进程需要的资源都获取到了,除了CPU
执行状态:获取到了所有资源包括CPU,进程处于运行状态
阻塞状态:进程停滞不再运行,放弃了CPU,进程此时处于内存里
什么叫进程?
正在运行的程序。
由代码段,数据段,PCB(进程控制块)
进程是资源分配的基本单位。
进程之间能不能直接通信?
正常情况下,多进程之间是无法直接进行通信的。因为每个进程都有自己独立的内存空间。
锁。为了多进程通信时,保护数据的安全性
一把锁配一把钥匙
l = Lock()
l.acquire()
l.release()
信号量。
一把锁配多把钥匙
sem = Semaphore(num)
num代表的是几把钥匙
事件。
e = Event()
e.is_set()返回一个bool值
e.wait() 阻塞和非阻塞
e.set() 把is_set的bool值变为True
e.clear() 把is_set的bool值变为False
今日内容:
1 生产者消费者模型
主要是为解耦
借助队列来实现生产者消费者模型
栈:先进后出(First In Last Out 简称 FILO)
队列: 先进先出(First In First Out 简称 FIFO)
import queue # 不能进行多进程之间的数据传输
(1)from multiprocessing import Queue 借助Queue解决生产者消费者模型
队列是安全的。
q = Queue(num)
num : 队列的最大长度
q.get()# 阻塞等待获取数据,如果有数据直接获取,如果没有数据,阻塞等待
q.put()# 阻塞,如果可以继续往队列中放数据,就直接放,不能放就阻塞等待
q.get_nowait()# 不阻塞,如果有数据直接获取,没有数据就报错
q.put_nowait()# 不阻塞,如果可以继续往队列中放数据,就直接放,不能放就报错
放:
from multiprocessing import Queue q = Queue(3) q.put(1) q.put('abc') q.put([4, 5, 6]) print(123) q.put('汉子') # 队列满了,无法放入,阻塞 print(456)
上面的例子阻塞了,如果用的是put_nowait 直接报错,加个try:
from multiprocessing import Queue q = Queue(3) q.put(1) q.put('abc') q.put([4, 5, 6]) print(123) try: q.put_nowait('汉子') except: print('队列满了') print(456)
取:
from multiprocessing import Queue q = Queue(3) q.put(1) q.put('abc') q.put([4, 5, 6]) print(q.get()) print(q.get()) print(q.get()) print(q.get()) # 阻塞等待
我们如果不想被阻塞了话。更改最后一行
try: print(q.get_nowait()) except: print('队列空了')
# 消费者如何判断,生产者是没来得及生产数据,还是生产者不再生产数据了?
# 如果你尝试用get_nowait() + try 的方式去尝试获得生产者不再生产数据,此时是有问题的。
用一个数据尾部加一个标识
1 from multiprocessing import Queue,Process 2 import time 3 4 def consumer(q,name): 5 while 1: 6 info = q.get() 7 if info: 8 print('%s 拿走了%s'%(name,info)) 9 else: # 当消费者获得队列中数据时,如果获得的是None,就是获得到了生产者不再生产数据的标识 10 break# 此时消费者结束即可 11 12 # 消费者如何判断,生产者是没来得及生产数据,还是生产者不再生产数据了? 13 # 如果你尝试用get_nowait() + try 的方式去尝试获得生产者不再生产数据,此时是有问题的。 14 15 def producer(q,product): 16 for i in range(20): 17 info = product + '的娃娃%s号'%str(i) 18 q.put(info) 19 q.put(None) # 让生产者生产完数据后,给消费者一个不再生产数据的标识 20 21 if __name__ == '__main__': 22 q = Queue(10) 23 p_pro = Process(target=producer,args=(q,'岛国米饭保你爱')) 24 p_con = Process(target=consumer,args=(q,'alex')) 25 p_pro.start() 26 p_con.start() 27
把标识放在主程序中
from multiprocessing import Queue,Process import time def consumer(q,name,color): while 1: info = q.get() if info: print('%s %s 拿走了%s 33[0m'%(color,name,info)) else:# 当消费者获得队列中数据时,如果获得的是None,就是获得到了生产者不再生产数据的标识 break# 此时消费者结束即可 def producer(q,product): for i in range(20): info = product + '的娃娃%s号'%str(i) q.put(info) if __name__ == '__main__': q = Queue(10) p_pro1 = Process(target=producer,args=(q,'岛国米饭保你爱')) p_pro2 = Process(target=producer,args=(q,'苍老师版')) p_pro3 = Process(target=producer,args=(q,'波多多版')) p_con1 = Process(target=consumer,args=(q,'alex','