根据cookbook, 多线程情况的事件驱动IO
来源:互联网 发布:淘宝反光衣 编辑:程序博客网 时间:2024/05/29 08:39
模拟使用线程池, 事件驱动IO模型, 这里使用的select
1. 采用对socket,初始化完成之后,内核状态是不可读,不可写(无东西可读)
2. 线程池完成工作之后, 回调_complete, 把线程计算结果及回调函数放入pending的list
3. 发送一个字节, 告诉内核select, 返回flieno那个socket可读,执行handle_receive把pending依次处理完成。
应用场景:
接收大量的fd,内存多大接多少
线程池处理结果
回调, fd清理收尾
#!/usr/bin/env pythonclass EventHandler(object): """An I/O event loop """ def fileno(self): raise NotImplemented def wants_to_receive(self): """Return True if receiving is allowed """ return False def handle_receive(self): """Perform the receive operation """ pass def wants_to_send(self): """Return True if sending is requested """ return False def handle_send(self): """send data """ passfrom concurrent.futures import ThreadPoolExecutorimport socketclass ThreadPoolHandler(EventHandler):def __init__(self, nworkers=3):a = socket.socket(socket.AF_INET, socket.SOCK_STREAM)a.bind(('127.0.0.1', 0))a.listen(1)connect_address = a.getsockname()self.writer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.writer.connect(connect_address)self.reader, addr = a.accept()a.close()self.pending = []self.pool = ThreadPoolExecutor(nworkers)def fileno(self):return self.reader.fileno()def _complete(self, callback, r):self.pending.append((callback, r.result()))self.writer.send(b'x') # wakedef run(self, func, args={}, kwargs={}, *, callback):r = self.pool.submit(func, *args, **kwargs)r.add_done_callback(lambda r: self._complete(callback, r))def wants_to_receive(self):return Truedef handle_receive(self):"""Run callback functions of complete work"""for callback, result in self.pending:callback(result)self.reader.recv(1) # recv xself.pending = []class UDPServer(EventHandler): """An UDP io event loop handler """ def __init__(self, address): self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(address) def fileno(self): return self.sock.fileno() def wants_to_receive(self): # blocking return True import select def event_loop(handlers): while True: wants_recv = [h for h in handlers if h.wants_to_receive()] wants_send = [h for h in handlers if h.wants_to_send()] can_recv, can_send, err = select.select(wants_recv, wants_send, []) for h in can_recv: h.handle_receive() for h in can_send: h.handle_send()def fib(n):if n < 2:return 1else:return fib(n-1) + fib(n-2)class UDPFibServer(UDPServer):def handle_receive(self):msg, addr = self.sock.recvfrom(1024)n = int(msg)pool.run(fib, (n,), callback=lambda r: self.respond(r, addr))def respond(self, result, addr):self.sock.sendto(str(result).encode("ascii"), addr)if __name__ == "__main__":pool = ThreadPoolHandler(16)handlers = [pool, UDPFibServer(('', 7777))]event_loop(handlers)
0 0
- 根据cookbook, 多线程情况的事件驱动IO
- python-cookbook事件驱动的i/o模型
- 多线程情况下libc IO的缓存
- 事件驱动IO-udp
- 事件驱动IO-tcp
- 事件驱动与异步IO
- 关于事件驱动的学习一 异步IO aio
- 使用gtk+的iochannel进行事件驱动IO操作
- Netty 基于事件驱动模型实现的异步IO
- Nodejs的单线程、异步IO与事件驱动
- 事件驱动的单线程模型 VS 多线程模型
- 多线程提高效率的情况
- 论事件驱动与异步IO
- as3 cookbook 处理事件
- 多线程 异步实现(通过事件驱动)
- python多线程在IO密集型情况下为什么会更快?
- python(十)下:事件驱动与 阻塞IO、非阻塞IO、IO多路复用、异步IO
- 根据情况确定正确的模型
- 内存溢出 PermGen space
- python编写登录接口
- AngularJS简介
- Nginx WEB服务器 win10启动不了
- 高并发量网站解决方案
- 根据cookbook, 多线程情况的事件驱动IO
- 商品关联分析
- ubuntu修复系统
- 今天才知道有了csdn账号不是就有了博客
- HDU 3085 Nightmare Ⅱ
- viewpagerindicator+UnderlinePageIndicator+ viewpage切换
- 根据wsdl生成一个webservice 的.cs文件
- Linux常用命令大全
- 数学基础知识之正弦、余弦