IO多路复用

O多路复用技术是使用一个可以同时监视多个IO阻塞的中间人去监视这些不同的IO对象,这些被监视的任何一个或多个IO对象有消息返回,都将会触发这个中间人将这些有消息IO对象返回,以供获取他们的消息。

使用IO多路复用的优点在于进程在单线程的情况下同样可以同时处理多个IO阻塞。与传统的多线程/多进程模型比,I/O多路复用系统开销小,系统不需要创建新的进程或者线程,也不需要维护这些进程和线程的运行,降底了系统的维护工作量,节省了系统资源,

Python提供了selector模块来实现IO多路复用。同时,不同的操作系统上,这中间人的可选则的类型是不同的,目前常见的有,epoll, kqueue, devpoll, poll,select等;kqueue(BSD,mac支持),devpoll(solaris支持)和epoll的实现基本相同,epoll在Linux2.5+内核中实现,Windows系统只实现了select。

epoll,poll, select的比较

select和poll使用轮询的方式去检测监视的所有IO是否有数据返回,需要不断的遍历每一个IO对象,这是一种费时的操作,效率较低。poll优于select的一点是select限制了最大监视IO数为1024,这对于需要大量网络IO连接的服务器来显然是不够的;而poll对于这个个数没有限制。但是这同样面临问题,在使用轮询的方式监视这些IO时,IO数越大,意味着每一次轮询消耗的时间越多。效率也就越低,这是轮询无法解决的问题。

epoll就是为了解决这样的问题诞生的,首先他没有最大的监视的IO数的限制,并且没有使用轮询的方式去检测这些IO,而是采用了事件通知机制和回调来获取这些有消息返回的IO对象,只有“活跃”的IO才会主动的去调用callback函数。这个IO将会直接被处理而不需要轮询。

selector模块的基本使用

importselectorsimportsocket#创建一个socketIO对象,监听后将可以接受请求消息了

sock =socket.socket()

sock.bind(("127.0.0.1", 80))

sock.listen()

slt= selectors.DefaultSelector() #使用系统默认selector,Windows为select,linux为epoll

#将这个socketIO对象加入到,select中监视

slt.register(fileobj=sock, events=selectors.EVENT_READ, data=None)#循环处理消息

whileTrue:#select方法:轮询这个selector,当有至少一个IO对象有消息返回时候,将会返回这个有消息的IO对象

ready_events = slt.select(timeout=None)print(ready_events) # 准备好的IO对象们break

运行上面的程序,打开浏览器访问127.0.0.1默认80端口,我们的服务器将会输出以下内容。

#ready_events为一个列表,列表中的每一个元组为一个IO对 和mask值(标识该对象是被读(1)还是写(2)激活的,此处为1)

[(SelectorKey(fileobj=,

fd=456, events=1, data=None), 1)]

该SelectorKey对象有三个属性

fileobj:注册的socket对象

fd:文件描述符

data:注册时我们传入的参数,可以是任意值,绑定到一个属性上,方便之后使用。

返回了一个列表,包含了注册到这个select中的所有的有数据可接收IO对象。我们通过浏览器访问该服务器后,该IO检测到请求消息,将会被返回等待处理。上面使用break是因为我们没有对这个被激活的IO做处理,select方法将会一直检测到这个激活信号,就会快速的死循环。可以去除break尝试一下。

处理这个请求,只需要使用该socket对应方法即可,该socket用于接收请求的连接,使用accept方法就可以处理这个请求。当接受请求之后,又将会产生新的客户端,我们将其放入selector中一并监视,当有消息来时,如果是连接请求,handle_request()函数处理,如果是客户端的消息,handle_client_msg()函数处理。下面是部分代码

#处理这连接请求

defhandle_request(sock:socket.socket):#使用accept方法可以将这个请求处理掉,该socket只有新的连接请求才会被再次被select检测。

conn, addr =sock.accept()#返回了一个新的socket,添加到同一个select中去监视它

slt.register(conn, selector.EVENT_READ, data=None)#此时slt中有两个socket,一个接受新的连接,一个与已连接客户端通信,我们需要做两个处理方法

defhandle_client_msg(sock:socket.socket)

data= sock.recv() #处理消息,

print(data.decode())whileTrue:

ready_events= slt.select(timeout=None)for event inready_events:if event.fileobj is sock: #新的用户连接请求,accept接受请求

handle_request(event.fileobj)else: #否则这是客户端的消息

handle_client_msg(event.fileobj)

于select中有两类socket,所以我们需要判断被激活后返回的socket是哪一种,再调用不同的函数做不同的请求。如果这个select中的socket种类有很多,将无法如此判断。解决办法就是将处理函数绑定到对应的selectkey对象中,可以使用data参数。

importselectorsimportsocketdef handle_request(sock:socket.socket): #处理新连接

conn, addr =sock.accept()

slt.register(conn, selector.EVENT_READ, data=handle_client_msg)def handle_client_msg(sock:socket.socket) #处理消息

data =sock.recv()print(data.decode())

sock=socket.socket()

sock.bind(("127.0.0.1", 80))

sock.listen()

slt=selectors.DefaultSelector()

slt.register(fileobj=sock, events=selectors.EVENT_READ, data=handle_request)whileTrue:

ready_events= slt.select(timeout=None)for event, _ inready_events:

event.data(event.fileobj)#不同的socket有不同data函数,使用自己绑定的data函数调用,再将自己的socket作为参数。就可以处理不同类型的socket。

上面使用data很好的解决了上面问题,但是需要注意,绑定到data属性上函数(或者说可调用对象)最终会使用event.data(event.fileobj)的方式调用,这些函数接受的参数应该相同。

python io多路复用_python实现IO多路复用 --- selector相关推荐

  1. python io多路复用_Python之IO多路复用

    一.IO模型介绍 ​ 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这 ...

  2. python io多路复用框架_python之IO多路复用

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

  3. Python之路--协程/IO多路复用

    引子: 之前学习过了,线程,进程的概念,知道了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把CPU的利用率提高很多了.但是我们知道无论是创建多进程还是创建多 ...

  4. python学习模型_python学习笔记(IO模型)

    1.IO模型介绍: io模型一般有五种: * blocking IO * nonblocking IO * IO multiplexing * signal driven IO * asynchron ...

  5. 网络传输中的两个阶段、阻塞IO、非阻塞IO和多路复用

    今天学习了网络传输中的两个阶段.阻塞IO.非阻塞IO和多路复用 一.网络传输中的两个阶段 分别是 waitdata 和 copydata send就是copydata recv是waitdata和co ...

  6. Linux网络编程 | IO模型 :阻塞IO、非阻塞IO、信号驱动IO、异步IO、多路复用IO

    目录 IO模型 阻塞与非阻塞 同步与异步 阻塞IO 非阻塞IO 信号驱动IO 多路复用IO 异步IO IO模型 根据各自的特性不同,IO模型被分为阻塞IO.非阻塞IO.信号驱动IO.异步IO.多路复用 ...

  7. 5种网络IO模型:阻塞IO、非阻塞IO、异步IO、多路复用IO、信号驱动IO

    目录 前言 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) 模型间的区别 ...

  8. IO模型 :阻塞IO、非阻塞IO、信号驱动IO、异步IO、多路复用IO

    文章目录 IO模型 阻塞IO 非阻塞IO 信号驱动IO 多路复用IO 异步IO IO模型 根据各自的特性不同,IO模型被分为阻塞IO.非阻塞IO.信号驱动IO.异步IO.多路复用IO五类. 最主要的两 ...

  9. 多路转接IO模型:多路转接多路复用

    IO模型:多路转接&多路复用 一.多路转接IO模型 (一)作用 (二)IO就绪事件 1.可读 2.可写 3.异常 二.技术实现 (一)select模型 1.select操作流程 2.Linux ...

最新文章

  1. 贪心 ---- C. Anu Has a Function位运算+贪心证明
  2. 一种电子病历系统软件框架思想
  3. 波士顿动力机器人齐秀舞姿,这是要成团出道?
  4. [转载]Word直接发布新浪博客(以Word 2013为例)
  5. 工厂模式——JavaScript
  6. ubuntu 下的ftp安装及root身份远程配置
  7. android IO流_Flutter实战经验(十):打包和发布到 Android 平台
  8. CFileDialog
  9. Office365—Exchange管理4—通讯组和安全组
  10. 设备管理(最近考试有考到,就转一下)
  11. SAPUI5教程——URLHelper的使用技巧
  12. 怎么用linux给苹果手机降级,如何查询iOS可降级版本?苹果iOS随意降级工具或即将到来...
  13. 计算机c盘用户里的APPDATA,什么是appdata C盘appdata可以删除吗
  14. curl: (67) Access denied: 530的可能原因
  15. 聚焦交通缓堵之东城篇,核心区如何重拳治堵
  16. 创始人、CEO、总裁和董事长到底谁更大?
  17. SpringCloud这35问,弄懂了面试官都不得不夸你一句
  18. opencv实战3-处理图像的颜色
  19. linux 运行脚本时报错:语法错误: 未预期的文件结尾
  20. 后门触发器之频域角度——Rethinking the Backdoor Attacks’ Triggers A Frequency Perspective

热门文章

  1. Hive权限与HDFS权限分离导致的一些问题
  2. 优化SQL查询:如何写出高性能SQL语句
  3. 封装的适配器 adapter
  4. 设计模式系列-组合模式
  5. DataGridView常见用法和FAQ汇总
  6. 其他信息: 线程间操作无效: 从不是创建控件“控件名”的线程访问它。
  7. loading加载和layer.js
  8. js window.open()实现打印,如何在关闭打印窗口时刷新父窗口
  9. 四道微软面试经典算法题
  10. 邮箱有什么用_大公司为什么要用企业邮箱?大公司企业邮箱用什么比较好?