python多线程与多进程异步事件框架
多线程简单实现
- #!/usr/bin/env python
- # -*- coding: UTF-8 -*-
- import logging
- import queue
- import threading
- from concurrent.futures import ThreadPoolExecutor
- # 任务:事件
- def func_a(a, b):
- return a + b
- def func_b(a, b):
- return a * b
- def func_c(a, b, c):
- return a * b - c
- # 回调函数
- def handle_result1(result):
- print(type(result), result)
- def handle_result2(result):
- print(type(result), result)
- def handle_result3(result):
- print(type(result), result)
- class EventEngine(object):
- # 初始化事件事件驱动引擎
- def __init__(self):
- # 保存事件列表:异步任务队列
- self.__eventQueue = queue.Queue()
- # 引擎开关
- self.__active = False
- # 事件处理字典{'event1': [handler1,handler2] , 'event2':[handler3, ...,handler4]}
- self.__handlers = {}
- # 事件引擎主进程
- self.__Thread = threading.Thread(target=self.task_queue_consumer)
- # 事件处理线程池
- self.__thread_pool = ThreadPoolExecutor(max_workers=5)
- # 线程处理存储
- self.__thread_Pool = []
- #注册事件
- def register(self,event, callback, *args, **kwargs):
- Event = {
- 'function': event,
- 'callback': callback,
- 'args': args,
- 'kwargs': kwargs
- }
- self.__handlers[event] = Event
- #注销事件
- def unregister(self,event):
- if(self.__handlers[event]):
- del self.__handlers[event]
- #提交事件
- def sendevent(self,event):
- if ( event in self.__handlers.keys()):
- self.__eventQueue.put(self.__handlers[event])
- # 开启事件引擎
- def start(self):
- self.__active = True
- self.__Thread.start()
- # 暂停事件引擎
- def stop(self):
- self.__active = False
- # 暂停后开始
- def restart(self):
- self.__active = True
- # 关闭事件引擎
- def close(self):
- pass
- # 开启事件循环
- def task_queue_consumer(self):
- """
- 异步任务队列
- """
- while(1):
- while self.__active:
- if (self.__eventQueue.empty() == False):
- try:
- task = self.__eventQueue.get()
- function = task.get('function')
- callback = task.get('callback')
- args = task.get('args')
- kwargs = task.get('kwargs')
- try:
- if callback:
- thread = self.__thread_pool.submit(callback,function(*args, **kwargs))
- self.__thread_Pool.append(thread)
- # callback(function(*args, **kwargs))
- except Exception as ex:
- if callback:
- callback(ex)
- finally:
- self.__eventQueue.task_done()
- except Exception as ex:
- logging.warning(ex)
- if __name__ == '__main__':
- import time
- #初始化多线程异步框架
- Engine = EventEngine()
- #启动
- Engine.start()
- #注册回调函数
- Engine.register(func_a, handle_result1, 1, 2)
- Engine.register(func_b, handle_result2, 1, 2)
- Engine.register(func_c, handle_result3, 1, 2, 3)
- #提交事件
- Engine.sendevent(func_a)
- Engine.sendevent(func_b)
- Engine.sendevent(func_c)
- time.sleep(2)
- Engine.stop()
- Engine.restart()
- Engine.sendevent(func_b)
- Engine.sendevent(func_c)
- # for i in range(100):
- # Engine.sendevent(func_a)
多进程实现
- 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()
多进程程序来源:http://blog.sina.com.cn/s/blog_13bb711fd0102x5nd.html
python多线程与多进程异步事件框架的更多相关文章
- Python多线程和多进程谁更快?
python多进程和多线程谁更快 python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很 ...
- python多线程与多进程--存活主机ping扫描以及爬取股票价格
python多线程与多进程 多线程: 案例:扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活) 普通版本: #扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活)im ...
- Python 多线程、多进程 (一)之 源码执行流程、GIL
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...
- Python 多线程、多进程 (二)之 多线程、同步、通信
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...
- Python 多线程、多进程 (三)之 线程进程对比、多进程
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.多线程与多进 ...
- python多线程与多进程及其区别
个人一直觉得对学习任何知识而言,概念是相当重要的.掌握了概念和原理,细节可以留给实践去推敲.掌握的关键在于理解,通过具体的实例和实际操作来感性的体会概念和原理可以起到很好的效果.本文通过一些具体的例子 ...
- 基于Windows平台的Python多线程及多进程学习小结
python多线程及多进程对于不同平台有不同的工具(platform-specific tools),如os.fork仅在Unix上可用,而windows不可用,该文仅针对windows平台可用的工具 ...
- python 多线程和多进程
多线程与多进程 知识预览 一 进程与线程的概念 二 threading模块 三 multiprocessing模块 四 协程 五 IO模型 回到顶部 一 进程与线程的概念 1.1 进程 考虑一个场景: ...
- 搞定python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
随机推荐
- Qt编写自定义控件56-波浪曲线
一.前言 波浪曲线控件,其实是之前一个水波进度条控件的一个核心,其实就是利用正弦曲线来生成对应的坐标进行绘制,把这个功能单独提取出来,是为了更详细的研究各种正弦余弦等拓展效果,当时写这个效果的时候,参 ...
- (十七)jdbc(Java Data Base Connectivity,java数据库连接)基础使用
一.JDBC相关概念介绍 1.1 JDBC介绍 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC.这套接口由数据库厂商去实现,这样,开发人员只需要学习 ...
- 【Leetcode_easy】690. Employee Importance
problem 690. Employee Importance 题意:所有下属和自己的重要度之和,所有下属包括下属的下属即直接下属和间接下属. solution:DFS; /* // Employe ...
- iOS技术面试02:内存管理
怎么保证多人开发进行内存泄露的检查. 如何定位内存泄露? 1> 使用Analyze进行代码的静态分析(检测有无潜在的内存泄露) 2> 通过leak检查在程序运行过程中有无内存泄露 3> ...
- .Net Core 常用开发工具
组件名 描述 可选版本 推荐版本 Visual Studio Community 社区免费版 For Visual Studio 2017 For Visual Studio 2019 Visual ...
- 使用GDAL进行波段分离
波段分离一般最常用的还是OpenCV,使用OpenCV的split方法可以直接对波段分离,并且效果不错,但是有一个问题是只能处理有限波段的数据,比如波段超过一定的数目就无法完成波段分离工作,或者数据有 ...
- 常见问题:计算机网络/运输层/TCP
TCP 面向连接,全双工,点对点. TCP头格式 TCP包没有IP地址,IP地址在网络层的IP协议中,TCP包包括源端口号,目标端口号 一个TCP连接需要四个元祖表明是同一连接(src_ip,src_ ...
- Qt598x64vs2017.Kit(构建套件)(安装Qt598x86vs2015)
1.Qt598-->工具-->选项 1.1. 1.2. 2.20191120 想起 上面第一张图的配置编译器的地方,就想着 Qt598x64vs2017 配置成编译x86,于是将 上面图中 ...
- JS通过ActiveX读写ini配置文件
String.prototype.trim = function(){ return this.replace(/(^\s+)|(\s+$)/g, ''); }; IniConfig = functi ...
- canvas画箭头demo
效果图: 代码: <!DOCTYPE html> <html> <title>canvas画箭头demo</title> <body> &l ...