这篇文章主要介绍了Python之输入输出多路复用指的是什么,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。
<强>输入输出多路复用(IO多路复用)强>
输入输出多路复用,有些地方称之为事件驱动IO(事件驱动IO)。
它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两个是函数,它会不断轮询所有的套接字,直到某个插座就绪有数据可达,就会通知用户进程,当用户进程调用了选择函数,选择是一个阻塞方法,会把进程阻塞住,同时会监听所有选择负责的插座,当任何一个套接字中的数据准备好了,选择就会返回。这个时候用户进程再调用readRecv操作,将数据从内核拷贝到用户进程。
选择虽然是阻塞的,但是它的优势在于它可以用一个进程处理多个连接,这个利用非阻塞的轮询方式是无法实现的,当连接数增多时优势就明显,而对于单个连接则跟同步IO区别不大甚至性能还要更低。
选择、调查,epoll都是输入输出多路复用的机制,输入输出多路复用就是通过机制用一个进程监视多个描述符,一旦某个描述符就绪(可读或者可写或者异常),能够通知进程进行响应的操作。但是选择、调查,epoll本质上是同步IO,因为他们都需要在读写事件就绪后自己负责读写,这个过程是阻塞的。
下面用Python的套接字编程模拟IO多路复用(IO多路复用+回调+事件循环)
class 取物: ,,,def 连接(自我,,键): ,,,,,,,selector.unregister (key.fd) ,,,,,,,self.con.send (& # 39; GET  {}, HTTP/1.1 \ r \ nHost: {} \ r \ nConnection:关闭\ r \ n \ r \ n # 39; .format (self.path self.host)。 ,,,,,,,编码(& # 39;utf - 8 # 39;)) ,,,,,,,selector.register (self.con.fileno (),, EVENT_READ,, self.read) ,,,def 读(自我,,键): ,,,,,,,d =, self.con.recv (1024) ,,,,,,,if d: ,,,,,,,,,,,印刷(d) ,,,,,,,,,,,self.data +=, d ,,,,,,,其他的: ,,,,,,,,,,,selector.unregister (key.fd) ,,,,,,,,,,,self.data =, self.data.decode (& # 39; utf - 8 # 39;) ,,,,,,,,,,,html_data =, self.data.split (& # 39; \ r \ n \ r \ n # 39;) [1] ,,,,,,,,,,,印刷(html_data) ,,,,,,,,,,,self.con.close () ,,,def get_url(自我,url): ,,,,,,,… ,,,,,,,self.con =, socket.socket (socket.AF_INET, socket.SOCK_STREAM) ,,,,,,,self.con.setblocking(假) ,,,,,,,#设置非阻塞 ,,,,,,,试一试: ,,,,,,,,,,,self.con.connect ((self.host, 80)) ,,,,,,,except BlockingIOError as e: ,,,,,,,,,,, ,,,,,,,selector.register (self.con.fileno (),, EVENT_WRITE,, self.connected)
过程:发送一个套接字请求设置为非阻塞,在选择函数中注册事件,self.con.fileno表示当前连接在进程中的描述符,EVENT_WRITE表示套准备是否就绪,self.connected为回调函数,准备完成后就调用.selector.unregister (key.fd)取消注册,发送HTTP请求,再调用selector.register (self.con.fileno (), EVENT_READ, self.read)注册,若当前请求内容可读,则调用读回调函数读取出响应内容。
注明:在windows下会调用选择函数,而在linux/unix下则会调用epoll函数。
完整代码如下:
import 插座 得到urllib.parse import  urlparse 得到selectors import  DefaultSelector, EVENT_READ, EVENT_WRITE 时间=selector DefaultSelector () class 取物: ,,,def 连接(自我,,键): ,,,,,,,selector.unregister (key.fd) ,,,,,,,self.con.send (& # 39; GET  {}, HTTP/1.1 \ r \ nHost: {} \ r \ nConnection:关闭\ r \ n \ r \ n # 39; .format (self.path self.host)。 ,,,,,,,编码(& # 39;utf - 8 # 39;)) ,,,,,,,selector.register (self.con.fileno (),, EVENT_READ,, self.read) ,,,def 读(自我,,键): ,,,,,,,d =, self.con.recv (1024) ,,,,,,,if d: ,,,,,,,,,,,印刷(d) ,,,,,,,,,,,self.data +=, d ,,,,,,,其他的: ,,,,,,,,,,,selector.unregister (key.fd) ,,,,,,,,,,,self.data =, self.data.decode (& # 39; utf - 8 # 39;) null null null null null null null null null null null null null null null null null null null null null null null null null null null nullPython之输入输出多路复用指的是什么