python之I/O多路复用
2016-07-11 12:00
555 查看
python IO多路复用
一、多路复用概念:
监听多个描述符(文件描述符(windows下暂不支持)、网络描述符)的状态,如果描述符状态改变 则会被内核修改标志位,进而被进程获取进而进行读写操作
二、多路复用两种触发方式:
水平触发(Level Triggered):
将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,但是会增加消耗
边缘触发(Edge Triggered):
只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,理论上边缘触发的性能要更高一些,但是代码实现相当复杂。
三、 阻塞/非阻塞 模式:
阻塞: 如果阻塞模式则等待数据
非阻塞: 如果非阻塞模式有数据返回数据、无数据直接返回报错
四、 I/O模型:
同步I/O: 一问一答 等待数据(阻塞模式)或 不管有没有数据都返回(非阻塞模式)
异步I/O: 用户进程问完之后干别的处理结果出来之后告知用户进程
五、 selec/poll/epoll
相同点和不同点图解
import socket import select import Queue # Create a TCP/IP socket, and then bind and listen server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setblocking(False) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_address = ("192.168.1.102", 10001) print "Starting up on %s port %s" % server_address server.bind(server_address) server.listen(5) message_queues = {} #The timeout value is represented in milliseconds, instead of seconds. timeout = 1000 # Create a limit for the event READ_ONLY = ( select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR) READ_WRITE = (READ_ONLY|select.POLLOUT) # Set up the poller poller = select.poll() poller.register(server,READ_ONLY) #Map file descriptors to socket objects fd_to_socket = {server.fileno():server,} while True: print "Waiting for the next event" events = poller.poll(timeout) print "*"*20 print len(events) print events print "*"*20 for fd ,flag in events: s = fd_to_socket[fd] if flag & (select.POLLIN | select.POLLPRI) : if s is server : # A readable socket is ready to accept a connection connection , client_address = s.accept() print " Connection " , client_address connection.setblocking(False) fd_to_socket[connection.fileno()] = connection poller.register(connection,READ_ONLY) #Give the connection a queue to send data message_queues[connection] = Queue.Queue() else : data = s.recv(1024) if data: # A readable client socket has data print " received %s from %s " % (data, s.getpeername()) message_queues[s].put(data) poller.modify(s,READ_WRITE) else : # Close the connection print " closing" , s.getpeername() # Stop listening for input on the connection poller.unregister(s) s.close() del message_queues[s] elif flag & select.POLLHUP : #A client that "hang up" , to be closed. print " Closing ", s.getpeername() ,"(HUP)" poller.unregister(s) s.close() elif flag & select.POLLOUT : #Socket is ready to send data , if there is any to send try: next_msg = message_queues[s].get_nowait() except Queue.Empty: # No messages waiting so stop checking print s.getpeername() , " queue empty" poller.modify(s,READ_ONLY) else : print " sending %s to %s" % (next_msg , s.getpeername()) s.send(next_msg) elif flag & select.POLLERR: #Any events with POLLERR cause the server to close the socket print " exception on" , s.getpeername() poller.unregister(s) s.close() del message_queues[s]View Code 参考、引用链接地址为:
http://www.cnblogs.com/Alanpy/p/5114706.html
http://www.cnblogs.com/coser/archive/2012/01/06/2315216.html
相关文章推荐
- python排序算法
- mac无法安装wxPython
- python struct模块
- python爬虫(1)下载任意网页图片
- python 使用lxml解析html(xpath)
- python中json对象转换出错解决方法
- saltstack学习汇总
- python2.0_s12_day12_css样式详解
- 使用python测试你的电脑开启最大线程数
- Python爬虫实战(3):安居客房产经纪人信息采集
- Python获取当前时间的前(后)N天,前(后)N周,前(后)N月
- Python新手学习基础之数据类型——变量
- 深入Python(2): __init__.py 用法
- TensorFlow实战— —K-Means聚类
- Celery 踩坑笔记
- DAY7:leetcode #14 Longest Common Prefix
- Python中关于字符串问题
- 关于python urlopen 一个类似radio流的timeout方法
- python平行(3):【parallel python】与【sklearn joblib的parallel和delayed】性能对比
- [Jenkins] Use python requests to programatically get and set Jenkins job configuration