IO multiplexing(IO多路复用)

IO多路复用,有些地方称之为event driven IO(事件驱动IO)。

它的好处在于单个进程可以处理多个网络IO请求。select/epoll这两个是函数,它会不断轮询所有的socket,直到某个socket就绪有数据可达,就会通知用户进程,当用户进程调用了select函数,select是一个阻塞方法,会把进程阻塞住,同时会监听所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用readRecv操作,将数据从内核拷贝到用户进程。

select虽然是阻塞的,但是它的优势在于它可以用一个进程处理多个连接,这个利用非阻塞的轮询方式是无法实现的,当连接数增多时优势就明显,而对于单个连接则跟同步IO区别不大甚至性能还要更低。

select,poll,epoll都是IO多路复用的机制,IO多路复用就是通过机制用一个进程监视多个描述符,一旦某个描述符就绪(可读或者可写或者异常),能够通知进程进行响应的操作。但是select,poll,epoll本质上是同步IO,因为他们都需要在读写事件就绪后自己负责读写,这个过程是阻塞的。

下面用Python的socket编程模拟IO多路复用(IO多路复用+回调+事件循环)

class Fetcher:
def connected(self, key):
selector.unregister(key.fd)
self.con.send('GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n'.format(self.path,self.host).encode('utf-8'))
selector.register(self.con.fileno(), EVENT_READ, self.read) def read(self, key):
d = self.con.recv(1024)
if d:
print(d)
self.data += d
else:
selector.unregister(key.fd)
self.data = self.data.decode('utf-8')
html_data = self.data.split('\r\n\r\n')[1]
print(html_data)
self.con.close() def get_url(self, url):
...
self.con = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.con.setblocking(False)
#设置非阻塞
try:
self.con.connect((self.host, 80))
except BlockingIOError as e:
pass
selector.register(self.con.fileno(), EVENT_WRITE, self.connected)

过程:发送一个socket请求设置为非阻塞,在select函数中注册事件,self.con.fileno表示当前连接在进程中的描述符,EVENT_WRITE表示socket准备是否就绪,self.connected为回调函数,准备完成后就调用。selector.unregister(key.fd)取消注册,发送HTTP请求,再调用selector.register(self.con.fileno(), EVENT_READ, self.read)注册,若当前请求内容可读,则调用read回调函数读取出响应内容。

注明:在windows下会调用select函数,而在linux/unix下则会调用epoll函数

完整代码如下:

import socket
from urllib.parse import urlparse
from selectors import DefaultSelector, EVENT_READ, EVENT_WRITE
selector = DefaultSelector() class Fetcher:
def connected(self, key):
selector.unregister(key.fd)
self.con.send('GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n'.format(self.path,self.host).encode('utf-8'))
selector.register(self.con.fileno(), EVENT_READ, self.read) def read(self, key):
d = self.con.recv(1024)
if d:
print(d)
self.data += d
else:
selector.unregister(key.fd)
self.data = self.data.decode('utf-8')
html_data = self.data.split('\r\n\r\n')[1]
print(html_data)
self.con.close() def get_url(self, url):
url = urlparse(url)
self.host = url.netloc
self.path = url.path
self.data = b''
if self.path == "":
self.path = '/' self.con = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.con.setblocking(False) try:
self.con.connect((self.host, 80))
except BlockingIOError as e:
pass
#注册
selector.register(self.con.fileno(), EVENT_WRITE, self.connected) def loop():
while True:
ready = selector.select()
for key, mask in ready:
callback = key.data
callback(key) if __name__ == '__main__':
fetcher = Fetcher()
fetcher.get_url('http://www.baidu.com')
loop()

IO多路复用select/poll/epoll详解以及在Python中的应用的更多相关文章

  1. Linux IO模式以及select poll epoll详解

    一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...

  2. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  3. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  4. 最快理解 - IO多路复用:select / poll / epoll 的区别.

    目录 第一个解决方案(多线程) 第二个解决方案(select) 第三个解决方案(poll) 最终解决方案(epoll) 客栈遇到的问题 从开始学习编程后,我就想开一个 Hello World 餐厅,由 ...

  5. Linux IO多路复用 select/poll/epoll

    Select -- synchronius I/O multiplexing select, FS_SET,FD_CLR,FD_ISSET,FD_ZERO #include <sys/time. ...

  6. python网络编程——IO多路复用select/poll/epoll的使用

    转载博客: http://www.haiyun.me/archives/1056.html http://www.cnblogs.com/coser/archive/2012/01/06/231521 ...

  7. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  8. 【操作系统】I/O多路复用 select poll epoll

    @ 目录 I/O模式 I/O多路复用 select poll epoll 事件触发模式 I/O模式 阻塞I/O 非阻塞I/O I/O多路复用 信号驱动I/O 异步I/O I/O多路复用 I/O 多路复 ...

  9. 多路复用select poll epoll

    I/O 多路复用之select.poll.epoll详解 select,poll,epoll都是IO多路复用的机制.I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般 ...

随机推荐

  1. css优化,提高性能

    CSS 优化主要是四个方面: 加载性能比如不要用 @import 等等,@import会影响css文件的加载速度,考虑加载性能时,主要是从减少文件体积.减少阻塞加载.提高并发方面入手,任何 hint ...

  2. php静态变量与方法与phar的使用

    本节用类与静态变量改造之前的例子:php根据命令行参数生成配置文件 ghostinit.php: <?php class ghostinit{ static $version = 'ghost ...

  3. Codeforces834A

    A. The Useless Toy time limit per test:1 second memory limit per test:256 megabytes input:standard i ...

  4. 令人血脉喷张的animate.css

    都说html5.css3是大局是潮流,尽管css3也不难,学起来比较简单,但我还是喜欢他的轻量级集大成者的animate.css框架,初学的小伙伴们加油啦 下面我分析一下animate.css框架里面 ...

  5. Dynamics 365Online 通过插件中的retrievemultiple消息来过滤产品视图

    本篇中要讲的是对产品视图基于某个条件进行过滤显示,而手段就是通过插件中的retrievemultiple消息,可能很多人都写过对它都不陌生. 先来看张插件注册的截图,插件的message是retrie ...

  6. java基础(十一) 枚举类型

    枚举类型Enum的简介 1.什么是枚举类型 枚举类型: 就是由一组具有名的值的有限集合组成新的类型.(即新的类). 好像还是不懂,别急,咱们先来看一下 为什么要引入枚举类型 在没有引入枚举类型前,当我 ...

  7. python中pip

    经常在安装软件过程中用pip 安装,当时的我总觉得pip是给linux还有mac用的,所以就从没有仔细研究过pip,后来用了python才知道pip这么好用 今天总结一下pip的用法 我的电脑是win ...

  8. ABP(ASP.NET Boilerplate Project)框架探讨

    从官网上下载下来带Module-Zero的abp框架. vs2015打开解决方案. 首先让系统run起来.把webconfig数据库连接改一下.启动程序. 发现报错:“本地语言指定”的错误,之后运行n ...

  9. 如何扩展 Azure 资源组中虚拟机的 OS 驱动器

    概述 在资源组中通过从 Azure 应用商店部署映像来创建新的虚拟机 (VM) 时,默认的 OS 驱动器空间为 127 GB. 尽管可以将数据磁盘添加到 VM(数量取决于所选择的 SKU),并且我们建 ...

  10. [Visual Studio] [Config] [Transformation] [SlowCheetah] 在非Web工程中使用Transformation

    1. 为VS安装SlowCheetah插件 https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.Sl ...