暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

python 多进程间相互协调: Event事件

小儿来一壶枸杞酒泡茶 2021-05-07
1527

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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论