多线程简单实现

#!/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多线程与多进程异步事件框架的更多相关文章

  1. Python多线程和多进程谁更快?

    python多进程和多线程谁更快 python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很 ...

  2. python多线程与多进程--存活主机ping扫描以及爬取股票价格

    python多线程与多进程 多线程: 案例:扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活) 普通版本: #扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活)im ...

  3. Python 多线程、多进程 (一)之 源码执行流程、GIL

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  4. Python 多线程、多进程 (二)之 多线程、同步、通信

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  5. Python 多线程、多进程 (三)之 线程进程对比、多进程

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.多线程与多进 ...

  6. python多线程与多进程及其区别

    个人一直觉得对学习任何知识而言,概念是相当重要的.掌握了概念和原理,细节可以留给实践去推敲.掌握的关键在于理解,通过具体的实例和实际操作来感性的体会概念和原理可以起到很好的效果.本文通过一些具体的例子 ...

  7. 基于Windows平台的Python多线程及多进程学习小结

    python多线程及多进程对于不同平台有不同的工具(platform-specific tools),如os.fork仅在Unix上可用,而windows不可用,该文仅针对windows平台可用的工具 ...

  8. python 多线程和多进程

    多线程与多进程 知识预览 一 进程与线程的概念 二 threading模块 三 multiprocessing模块 四 协程 五 IO模型 回到顶部 一 进程与线程的概念 1.1 进程 考虑一个场景: ...

  9. 搞定python多线程和多进程

    1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...

随机推荐

  1. Ubuntu 14.04 apache安装配置

    http://jingyan.baidu.com/article/6d704a130c8a0d28da51ca5f.html Ubuntu 14.04 apache安装配置 1.安装 ~# apt-g ...

  2. mysql修改时区的几种方法

    说明: 以下记录修改mysql时区的几种方法. 具体:方法一:通过mysql命令行模式下动态修改1.1 查看mysql当前时间,当前时区 > select curtime(); #或select ...

  3. 基于OpenCV的同态滤波

    在4.0.1节中,我们已经介绍了一个简单的图像形成模型,即照射-反射模型.这个模型可以开发一种频率处理程序,该程序可以同时压缩灰度范围和增强对比度来改善一幅图像的表现.图像形成的照射-反射模型的表达式 ...

  4. windows下进程与线程

    windows下进程与线程 Windows是一个单用户多任务的操作系统,同一时间可有多个进程在执行.进程是应用程序的运行实例,可以理解为应用程序的一次动态执行:而线程是CPU调度的单位,是进程的一个执 ...

  5. 深入理解 Css3 的 clip-path

    clip-path CSS 属性可以创建一个只有元素的部分区域可以显示的剪切区域.区域内的部分显示,区域外的隐藏.clip-path属性代替了现在已经弃用的剪切 clip属性.clip-path的属性 ...

  6. Ribbon【负载均衡策略】

    ribbon有7种负载均衡策略可供选择: 策略类 命名 描述 RandomRule 随机策略 随机选择server RoundRobinRule 轮询策略 按照顺序选择server(ribbon默认策 ...

  7. MarkdownPad 2 用 LaTeX 编写公式(17)

    方法一:(可离线显示) 1.解压「jaxedit-master.zip」,解压后找到「jaxedit-master」文件夹下「MathJax.js」文件的路径,这个文件在该文件下的路径是「jaxedi ...

  8. 串口(USART)通信-串口通讯协议简介

    物理层:规定通讯系统中具有机械.电子功能部分的特性,确保原始数据在物理媒体的传输.其实就是硬件部分. 协议层:协议层主要规定通讯逻辑,统一收发双方的数据打包.解包标准.其实就是软件部分. 简单来说物理 ...

  9. 读取一整行,保留空白,直到遇到换行符:getline()

  10. oracle 数据库 主键索引重建

    oracle 数据库 主键索引重建 alter table table_name drop primary key; alter table table_name add constraint pk_ ...