多线程简单实现

#!/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. 005-多线程-集合-Map-ConcurrentSkipListMap

    一.概述 ConcurrentSkipListMap是线程安全的有序的哈希表,适用于高并发的场景. ConcurrentSkipListMap和TreeMap,它们虽然都是有序的哈希表.但是,第一,它 ...

  2. QML之信号与槽

    一.C++的信号和QML的槽 前言: Qt中的信号与槽,通常是一个信号SIGNAL和一个槽SLOT,通过connet连接,而QML中不需要再写槽函数,只需要在合适的地方告诉QML:如果x信号产生则执行 ...

  3. 一个小时学会Git(转载)

    ---恢复内容开始--- 一个小时学会Git     最近要与部门同事一起做技术分享,我选择了Git,因为Git 是一种在全球范围都广受欢迎的版本控制系统.在开发过程中,为了跟踪代码,文档,项目等信息 ...

  4. Block pool ID needed, but service not yet registered with NN java.lang.Exception: trace 异常解决

    以上为报错信息: 原因大概为:dd和nd关联的versionId不同导致, 解决方案,备份之前的current文件夹,让其自己生成新的.

  5. SpringMvc+ajax跨域请求时,出现options类型的请求并返回403的解决方案

    在使用 $.ajax({ url:'http://127.0.0.1:8081/rest/ccxxx/xxxx', type:'POST', dataType:"json", co ...

  6. 第十五章 单点登录——《跟我学Shiro》

    目录贴:跟我学Shiro目录贴 Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个 ...

  7. iOS-AVPlayer

    MPMoviePlayerController足够强大,几乎不用写几行代码就能完成一个播放器,但是正是由于它的高度封装使得要自定义这个播放 器变得很复杂,甚至是不可能完成.例如有些时候需要自定义播放器 ...

  8. 【数据库开发】windows环境下通过c++使用redis

    1.Windows下Redis的安装使用 Redis是一个key-value存储系统.Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起 ...

  9. MacOS这idea快捷键

    Control + Space 基本的代码补全(补全任何类.方法.变量) Control + Shift + Space 智能代码补全(过滤器方法列表和变量的预期类型) Command + Shift ...

  10. vue报错:Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

    在.vue文件中引入了 element-ui 的 table 和 pagination 组件后,报错:Component template should contain exactly one roo ...