multiprocessing 多进程之间相互协调的方式有如下几种:
Lock:锁, Semaphore:信号量 Queue:队列, Event:事件 Pipe:管道
在多进程方式并发编程中,
如果我们实在无法避免进行数据共享的话(通常应该会尽量避免使用共享数据的方式进行通讯)应尽可能使用消息传递和队列,这样我们可以避免处理复杂的同步和锁问题,
multiprocessing模块为提供了基于消息的IPC通信机制:队列和管道。
队列和管道都是将数据存放于内存中。
队列又是基于(管道+锁)实现的,
基于消息的IPC通信机制通常可以让我们从复杂的锁问题中解脱出来。
1 Event 方式的进程间同步通信
Event提供一种简单的方法,可以在进程间传递状态信息,实现进程间同步通信(不同的进程之间可以利用一些特殊的处理来等待其他进程处理完毕)
Event可以切换设置和未设置状态。通过使用一个可选的超时值,事件对象的用户可以等待其状态从未设置变为设置状态。
事件event运行的机制:
全局定义了一个Flag
如果Flag值为 False,当程序执行event.wait()方法时就会阻塞
如果Flag值为True时,程序执行event.wait()方法时不会阻塞继续执行
事件event几个方法:
wait()方法:等待是否阻塞依赖全局的Flag的值。
PS:当调用wait()方法是将进入到阻塞状态,同时会设置阻塞标记为“False”,(待阻塞标记为“True"后才会解除阻塞状态,然后继续当前进程的任务执行,wait是切换当前的状态,转移执行权)
set()方法:将Flag的值改成True
clear()方法:将Flag的值改成False
is_set()方法:判断当前的Flag的值
#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
文件名称 : jincheng4
文件功能描述 : 功能描述
创建人 : 小钟同学
创建时间 : 2021/5/7
-------------------------------------------------
修改描述-2021/5/7:
-------------------------------------------------
全局定义了一个Flag
- 如果Flag值为 False,当程序执行event.wait()方法时就会阻塞
- 如果Flag值为True时,程序执行event.wait()方法时不会阻塞继续执行
### 事件event几个方法:
- wait()方法:等待是否阻塞依赖全局的Flag的值。
- set()方法:将Flag的值改成True
- clear()方法:将Flag的值改成False
- is_set()方法:判断当前的Flag的值
"""
import multiprocessing,time,random
def restaurant_handle(event):
print("肯德基开门了!!")
print("【服务员-1】当前事件状态:",event.is_set())
print("1、【服务员】请问你要吃点什么吗?。。。")
time.sleep(random.randint(1,3))
event.set()#解除阻塞状态
event.clear()#清除已有的状态
# 当调用wait()方法是将进入到阻塞状态,同时会设置阻塞标记为“False”,(待阻塞标记为“True"后才会接触阻塞状态)
event.wait()#等待客人点餐之后,才能进行下一步的后续处理
print("3、【服务员】你自己一个人这么能吃啊!。。。")
time.sleep(random.randint(1,3))
event.set() #解除阻塞状态
event.clear() # 之前的状态清空
event.wait()
print("5、【服务员】好的,我现在就给你下单,请你稍等。。。")
time.sleep(random.randint(1,3))
event.set() # 解除阻塞状态
event.clear() # 之前的状态清空
event.wait()
print("7、【服务员】好的,你稍等一下~~~。。。")
time.sleep(random.randint(1,3))
event.set()
# event.clear()
# event.wait()
print("8、【服务员】客人你点的:一个鸡腿+一个汉堡+一个这么大的鸡排 已做好了!请慢慢享用!")
time.sleep(random.randint(1,3))
# event.set()
# event.clear()
event.wait()
print("11、【服务员】好的,总共消费1000快!。。。")
time.sleep(random.randint(1, 3))
event.set() # 解除阻塞状态
event.clear() # 之前的状态清空
event.wait()
def diners_hangle(event):#食客的处理进程
print("当前事件状态:", event.is_set())
event.wait() #等待之前的第一步完成 两个进程所以先阻塞,让另一个执行
print("2、【客人】我要点一个鸡腿+一个汉堡+一个这么大的鸡排!。。。")
time.sleep(random.randint(1,3))
event.set() #解除阻塞状态
event.clear()#之前的状态清空
event.wait()#继续等待后续的处理步骤
print("4、【客人】怎么不可以吗?快下单吧~我都饿的叽里咕噜了~")
time.sleep(random.randint(1,3))
event.set()
event.clear()
event.wait()
print("6、【客人】让师傅做快一点。。。")
time.sleep(random.randint(1,3))
event.set()
event.clear()
event.wait()
print("9、【客人】好的,我开始吃了~~~~")
# event.set()
time.sleep(random.randint(1, 3))
print("10、【客人】吃完了!服务员,我买单!!!~~~~")
time.sleep(random.randint(1, 3))
event.set()
event.clear()
event.wait()
print("12、【客人】这么黑~~1000快!!不给!!我跑了!再见!~~~~")
event.set()
def main():
# 定义一个event同步处理,默认是处于阻塞的状态
event = multiprocessing.Event()
restaurant_process = multiprocessing.Process(target=restaurant_handle,args=(event,),name="肯德基服务进程")
diners_process = multiprocessing.Process(target=diners_hangle,args=(event,),name="客人进程")
restaurant_process.start()
diners_process.start()
if __name__ == '__main__':
main()
输出结果为:
D:\ceshi>python jincheng5.py
肯德基开门了!!
【服务员-1】当前事件状态:False
1、【服务员】请问你要吃点什么吗?。。。
当前事件状态:False
2、【客人】我要点一个鸡腿+一个汉堡+一个这么大的鸡排!。。。
3、【服务员】你自己一个人这么能吃啊!。。。
4、【客人】怎么不可以吗?快下单吧~我都饿的叽里咕噜了~
5、【服务员】好的,我现在就给你下单,请你稍等。。。
6、【客人】让师傅做快一点。。。
7、【服务员】好的,你稍等一下~~~。。。
8、【服务员】客人你点的:一个鸡腿+一个汉堡+一个这么大的鸡排 已做好了!请慢慢享用!
9、【客人】好的,我开始吃了~~~~
10、【客人】吃完了!服务员,我买单!!!~~~~
11、【服务员】好的,总共消费1000快!。。。
12、【客人】这么黑~~1000快!!不给!!我跑了!再见!~~~~
个人其他博客地址
简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
小钟同学 | 文 【原创】| QQ:308711822
1:本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。 2:关于文章内容,有部分内容参考自互联网,如有链接会声明标注;如没有及时标注备注的链接的,如有侵权请联系,我会立即删除处理哟。
文章转载自小儿来一壶枸杞酒泡茶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




