多线程简单实现

#!/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. 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_03-Eureka注册中心-搭建Eureka高可用环境

    1.3.2.2 高可用环境搭建 Eureka Server 高可用环境需要部署两个Eureka server,它们互相向对方注册.如果在本机启动两个Eureka需要 注意两个Eureka Server ...

  2. Qt编写自定义控件51-可输入仪表盘

    一.前言 这个控件是近期定制的控件,还是比较实用的控件之一,用户主要是提了三点需求,一点是切换焦点的时候控件放大突出显示,一点是可直接输入或者编辑值,还有一点是支持上下键及翻页键和鼠标滚轮来动态修改值 ...

  3. java 利用poi 实现excel合并单元格后出现边框有的消失的解决方法

    使用工具类RegionUtil CellRangeAddress cra = new CellRangeAddress(nowRowCount, nowRowCount + followSize-1, ...

  4. 使用select和show命令查看mysql数据库系统信息

    (1).select 显示当前日期和时间 mysql> select now(); +---------------------+ | now() | +-------------------- ...

  5. esxi 配置 交换主机 虚拟机交换机 linux centos 配置双网卡

    最近手里的项目网络环境是 192.168.199.1 直接到防火墙 192.168.1.x 是内网网段 走到 防火墙下的一个三层交换机 现在需要将内网的三台服务器端口映射出去,需要到防火墙去做映射,防 ...

  6. rhel7免密登录问题

    以前在做linux免密登录时只要执行:cat id_rsa.pub>> authorized_keys,就可以了 后来升级到rhel7之后不行,发现有两个需要改动: 1.修改ssh的配置文 ...

  7. Node.js使用MySQL连接池示例

    下面是一个封装好的工具类: var fs = require('fs'); var mysql = require('mysql'); var pool = mysql.createPool({ ho ...

  8. Redis学习笔记——Redis的基本操作

    之前介绍过如何在ubuntu安装Redis服务器:https://www.cnblogs.com/zifeiy/p/9062738.html 接下来,我们在Redis上进行一些基本的操作. 所县使用命 ...

  9. ubuntu 18.04安装mysql 8

    wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb sudo dpkg -i mysql-apt-config_0. ...

  10. ubuntu 18.04安装jdk8和eclipse

    JDK8的安装 1.安装ppa sudo add-apt-repository ppa:webupd8team/java sudo apt-get update 2.安装JDK sudo apt-ge ...