详解Python实现多进程异步事件驱动引擎


Posted in Python onAugust 25, 2017

本文介绍了详解Python实现多进程异步事件驱动引擎,分享给大家,具体如下:

多进程异步事件驱动逻辑

详解Python实现多进程异步事件驱动引擎

逻辑

code

# -*- coding: utf-8 -*-

'''
author:    Jimmy
contact:   234390130@qq.com
file:     eventEngine.py
time:     2017/8/25 上午10:06
description: 多进程异步事件驱动引擎

'''

__author__ = 'Jimmy'


from multiprocessing import Process, Queue


class EventEngine(object):
  # 初始化事件事件驱动引擎
  def __init__(self):
    #保存事件列表
    self.__eventQueue = Queue()
    #引擎开关
    self.__active = False
    #事件处理字典{'event1': [handler1,handler2] , 'event2':[handler3, ...,handler4]}
    self.__handlers = {}
    #保存事件处理进程池
    self.__processPool = []
    #事件引擎主进程
    self.__mainProcess = Process(target=self.__run)


  #执行事件循环
  def __run(self):
    while self.__active:
      #事件队列非空
      if not self.__eventQueue.empty():
        #获取队列中的事件 超时1秒
        event = self.__eventQueue.get(block=True ,timeout=1)
        #执行事件
        self.__process(event)
      else:
        # print('无任何事件')
        pass


  #执行事件
  def __process(self, event):
    if event.type in self.__handlers:
      for handler in self.__handlers[event.type]:
        #开一个进程去异步处理
        p = Process(target=handler, args=(event, ))
        #保存到进程池
        self.__processPool.append(p)
        p.start()


  #开启事件引擎
  def start(self):
    self.__active = True
    self.__mainProcess.start()


  #暂停事件引擎
  def stop(self):
    """停止"""
    # 将事件管理器设为停止
    self.__active = False
    # 等待事件处理进程退出
    for p in self.__processPool:
      p.join()
    self.__mainProcess.join()


  #终止事件引擎
  def terminate(self):
    self.__active = False
    #终止所有事件处理进程
    for p in self.__processPool:
      p.terminate()
    self.__mainProcess.join()


  #注册事件
  def register(self, type, handler):
    """注册事件处理函数监听"""
    # 尝试获取该事件类型对应的处理函数列表,若无则创建
    try:
      handlerList = self.__handlers[type]
    except KeyError:
      handlerList = []
      self.__handlers[type] = handlerList

    # 若要注册的处理器不在该事件的处理器列表中,则注册该事件
    if handler not in handlerList:
      handlerList.append(handler)


  def unregister(self, type, handler):
    """注销事件处理函数监听"""
    # 尝试获取该事件类型对应的处理函数列表,若无则忽略该次注销请求
    try:
      handlerList = self.__handlers[type]

      # 如果该函数存在于列表中,则移除
      if handler in handlerList:
        handlerList.remove(handler)

      # 如果函数列表为空,则从引擎中移除该事件类型
      if not handlerList:
        del self.__handlers[type]
    except KeyError:
      pass


  def sendEvent(self, event):
    #发送事件 像队列里存入事件
    self.__eventQueue.put(event)


class Event(object):
  #事件对象
  def __init__(self, type =None):
    self.type = type
    self.dict = {}



#测试
if __name__ == '__main__':
  import time
  EVENT_ARTICAL = "Event_Artical"

  # 事件源 公众号
  class PublicAccounts:
    def __init__(self, eventManager):
      self.__eventManager = eventManager

    def writeNewArtical(self):
      # 事件对象,写了新文章
      event = Event(EVENT_ARTICAL)
      event.dict["artical"] = u'如何写出更优雅的代码\n'
      # 发送事件
      self.__eventManager.sendEvent(event)
      print(u'公众号发送新文章\n')


  # 监听器 订阅者
  class ListenerTypeOne:
    def __init__(self, username):
      self.__username = username

    # 监听器的处理函数 读文章
    def ReadArtical(self, event):
      print(u'%s 收到新文章' % self.__username)
      print(u'%s 正在阅读新文章内容:%s' % (self.__username, event.dict["artical"]))


  class ListenerTypeTwo:
    def __init__(self, username):
      self.__username = username

    # 监听器的处理函数 读文章
    def ReadArtical(self, event):
      print(u'%s 收到新文章 睡3秒再看' % self.__username)
      time.sleep(3)
      print(u'%s 正在阅读新文章内容:%s' % (self.__username, event.dict["artical"]))


  def test():
    listner1 = ListenerTypeOne("thinkroom") # 订阅者1
    listner2 = ListenerTypeTwo("steve") # 订阅者2

    ee = EventEngine()

    # 绑定事件和监听器响应函数(新文章)
    ee.register(EVENT_ARTICAL, listner1.ReadArtical)
    ee.register(EVENT_ARTICAL, listner2.ReadArtical)
    for i in range(0, 20):
      listner3 = ListenerTypeOne("Jimmy") # 订阅者X
      ee.register(EVENT_ARTICAL, listner3.ReadArtical)

    ee.start()

    #发送事件
    publicAcc = PublicAccounts(ee)
    publicAcc.writeNewArtical()

  test()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中exit、return、sys.exit()等使用实例和区别
May 28 Python
python3实现UDP协议的服务器和客户端
Jun 14 Python
Python 网页解析HTMLParse的实例详解
Aug 10 Python
Python实现自动发送邮件功能
Mar 02 Python
Python面向对象之类的封装操作示例
Jun 08 Python
Python实现朴素贝叶斯的学习与分类过程解析
Aug 24 Python
python自动识别文本编码格式代码
Dec 26 Python
基于python 凸包问题的解决
Apr 16 Python
快速了解Python开发环境Spyder
Jun 29 Python
详解Java中一维、二维数组在内存中的结构
Feb 11 Python
PyTorch 如何检查模型梯度是否可导
Jun 05 Python
Python实现PIL图像处理库绘制国际象棋棋盘
Jul 16 Python
python基础while循环及if判断的实例讲解
Aug 25 #Python
itchat和matplotlib的结合使用爬取微信信息的实例
Aug 25 #Python
用 Python 爬了爬自己的微信朋友(实例讲解)
Aug 25 #Python
详解python基础之while循环及if判断
Aug 24 #Python
用Python实现随机森林算法的示例
Aug 24 #Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
Aug 24 #Python
python 接口_从协议到抽象基类详解
Aug 24 #Python
You might like
通过具体程序来理解PHP里面的抽象类
2010/01/28 PHP
初次接触php抽象工厂模式(Elgg)
2010/03/21 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
基于linnux+phantomjs实现生成图片格式的网页快照
2015/04/15 PHP
php数组函数array_walk用法示例
2016/05/26 PHP
JS中的public和private对象,即static修饰符
2012/01/18 Javascript
jquery 利用show和hidden实现级联菜单示例代码
2013/08/09 Javascript
javascript的日期对象、数组对象、二维数组使用说明
2014/12/22 Javascript
jQuery中unbind()方法用法实例
2015/01/19 Javascript
使用jQuery实现input数值增量和减量的方法
2015/01/24 Javascript
JavaScript中数据结构与算法(四):串(BF)
2015/06/19 Javascript
jQuery实现鼠标经过像翻页和描点链接效果
2016/08/08 Javascript
微信小程序 POST请求(网络请求)详解及实例代码
2016/11/16 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
AngularJS全局警告框实现方法示例
2017/05/18 Javascript
JS运动改变单物体透明度的方法分析
2018/01/23 Javascript
Vue 实现列表动态添加和删除的两种方法小结
2018/09/07 Javascript
vue里input根据value改变背景色的实例
2018/09/29 Javascript
解决angular双向绑定无效果,ng-model不能正常显示的问题
2018/10/02 Javascript
用Fundebug插件记录网络请求异常的方法
2019/02/21 Javascript
详解python3实现的web端json通信协议
2016/12/29 Python
Python遍历pandas数据方法总结
2018/02/09 Python
Python3实现转换Image图片格式
2018/06/21 Python
用Python解决x的n次方问题
2019/02/08 Python
python+mysql实现学生信息查询系统
2019/02/21 Python
python异步编程 使用yield from过程解析
2019/09/25 Python
Python socket模块方法实现详解
2019/11/05 Python
关于Flask项目无法使用公网IP访问的解决方式
2019/11/19 Python
Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
2020/05/11 Python
解决keras加入lambda层时shape的问题
2020/06/11 Python
北美Newegg打造的全球尖货海购平台:tt海购
2018/09/28 全球购物
仓库规划计划书
2014/04/28 职场文书
幼儿园教师师德师风演讲稿:我自豪我是一名幼师
2014/09/10 职场文书
2015年秋季小学开学标语
2015/07/16 职场文书
2019大学毕业晚会主持词
2019/06/21 职场文书
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技