上上篇博客讲的套接字,由于其阻塞性而导致一个服务端同一时间只能与一个客户端连接。基于这个缺点,在上篇博客我们将其设置为非阻塞实现了一个服务端同一时间可以与多个客户端相连,即实现了并发,但其同样留下了一个缺点:CPU的利用率低。这一篇博客是基于这个缺点再进一步进行改善,即实现并发,又提高CPU的利用率。

什么是epoll

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。epoll是当前Linux下效率最高的IO多路复用技术,值得一提的是,epoll是一个惰性的事件回调,操作系统仅仅起到监听作用,对于是否有连接请求发过来了,它需要用户自己去查询。

IO多路复用技术

在之前,我们一直都是利用监听套接字去接收客户端的连接请求,如果连接请求一直没来,就会一直处于无用的循环。但如果利用epoll的IO多路复用技术,我们就可以将socket的监听工作交给操作系统,而其本身可以去做其他的事情。在python中我们要用到的模块是selectors,selectors模块是在python3.4版本中引进的,它封装了IO多路复用中的select和epoll,能够更快,更方便的实现多并发效果。抛开套接字,它的大体流程如下:

  1. 实例化一个epoll选择器
  2. 对epoll选择器进行注册,从而起到让操作系统去监听,参数有套接字、事件、回调函数。它会把刚生成的sock连接对象注册到select连接列表中,并交给accept函数处理 。
  3. 对select进行查找,若查找为空,默认是阻塞,否则返回活动的连接列表。
  4. 调用回调函数
  5. 注销选择器

selectors模块的官方文档

事件的类型:

1.可读事件select.EVENT_READ   2.可写事件select.EVENT_WRITE

服务端代码:

import socket
import selectors def acce(server):#对客户端的请求建立连接
a, b = server.accept()
select.register(a,selectors.EVENT_READ,recv)#有信息发过来才会触发事件
def recv(a):#对已建立连接的客户端进行收发信息
date = a.recv(1024)
if date:
print("已收到信息-->{}".format(date.decode()))
a.send(date)
else:
select.unregister(a)
a.close() server = socket.socket()
server.bind(('127.0.0.5',8520))
server.listen(50)
select = selectors.DefaultSelector()#selectors模块默认会用epoll,如果你的系统中没有epoll(比如windows)则会自动使用select
select.register(server,selectors.EVENT_READ,acce)#有连接请求过来才会触发事件,第一个参数是套接字,第二个是事件类型,第三个是回调函数。
while True:
events = select.select()#触发的事件需要自己的查询, 默认是阻塞,有活动连接就返回活动的连接列表
for i,j in events:
callback = i.data #回调函数
sock = i.fileobj #套接字
callback(sock)#调用回调函数

客户端代码

import socket

client = socket.socket()
client.connect(('127.0.0.5',8520))
mess = input('--->').encode()
client.send(mess)
print("已收到回应-->{}".format(client.recv(1024)))
client.close()

上述服务端代码中,epoll选择器注册后对象结构如下图,只有请求连接过来时才会触发到的这个事件,但事件本身需要自己查询。

事件被触发后自己手动查询,特别的是如果没有事件,即没有客户端的请求连接,这里会有阻塞。当有事件时,他会返回一个列表的二元组。

这个事件中被我们用到的信息有两个,一个是套接字,一个是回调函数。可以将其直接取出来或如上图代码一样先拆包再取出来。下图是直接取出来。

总结:上述代码的效果也实现了并发,可以让一个服务端同时与多个客户端相连,相对于非阻塞套接字实现的并发,这里提高了CPU的利用率,因为这里是让操作系统充当监听工作,当选择器查找为空时,选择器会因为阻塞停止工作,若不为空,它会调用回调函数进行下一步工作。对于收发信息,它也是注册了一个事件,从而交给操作系统去监听,不需要对等连接套接字一直循环去监视。

epoll——IO多路复用选择器的更多相关文章

  1. epoll—IO多路复用

    1.在socket.listen()后创一个epoll对象   epoll = select.epoll() 2.将server_socket注册到epoll中        epoll.regist ...

  2. epoll IO多路复用(异步阻塞AIO)

    epoll的异步阻塞(AIO): 用户线程创建epoll后,其实是内核线程负责扫描 fd 列表(在网络服务器上可以是socket,socket在创建后返回的也是文件描述符),并填充事件链表.但是,并不 ...

  3. 【python】-- IO多路复用(select、poll、epoll)介绍及实现

    IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...

  4. IO多路复用(select、poll、epoll)介绍及select、epoll的实现

    IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...

  5. 11 非阻塞套接字与IO多路复用(进阶)

    1.非阻塞套接字 第一部分 基本IO模型 1.普通套接字实现的服务端的缺陷 一次只能服务一个客户端! 2.普通套接字实现的服务端的瓶颈!!! accept阻塞! 在没有新的套接字来之前,不能处理已经建 ...

  6. 利用IO多路复用,使用linux下的EpollSelector实现并发服务器

    import socket import selectors # IO多路复用选择器的模块 # 实例化一个和epoll通信的选择器 epoll_selector = selectors.EpollSe ...

  7. 异步、非阻塞和IO多路复用总结

    Nginx是并发处理框架的代表者,很多后台业务都会放在Nginx容器中运行,以实现高吞吐,而Nginx能够支持高并发也是由于使用了异步非阻塞处理模型,本文将用通俗的话讲解异步.同步.阻塞.非阻塞的区别 ...

  8. 网络编程基础【day10】:IO多路复用

    这些名词比较绕口,理解涵义就好.一个epoll场景:一个酒吧服务员(一个线程),前面趴了一群醉汉,突然一个吼一声“倒酒”(事件),你小跑过去给他倒一杯,然后随他去吧,突然又一个要倒酒,你又过去倒上,就 ...

  9. Python全栈开发-Day10-进程/协程/异步IO/IO多路复用

    本节内容 多进程multiprocessing 进程间的通讯 协程 论事件驱动与异步IO Select\Poll\Epoll——IO多路复用   1.多进程multiprocessing Python ...

随机推荐

  1. Tomcat JDK MySql 安装配置

    Tomcat 7绿色版指定jdk并注册服务  https://blog.csdn.net/weixin_43976019/article/details/89386171   例如:service.b ...

  2. 关联容器--保存指针时要指定容器的比较类型---引用Effective STL

    无论何时你建立指针的关联容器,注意你也得指定容器的比较类型.大多数时候,你的比较类型只是解引用指针并比较所指向的对象(就像上面的StringPtrLess做的那样).鉴于这种情况,你手头最好也能有一个 ...

  3. Day3-T2

    原题目 奶牛Bessie的电脑总是无缘无故地被 FJ 关掉,奶牛 Bessie 非常苦恼,也非常生气.FJ 却发现了 一个很神奇的规律(别问是怎么知道的),发现 Bessie 每吃一次草,她的生气值会 ...

  4. svn报错:“Previous operation has not finished; run 'cleanup' if it was interrupted“

    今天在eclipse上使用SVN:team - 显示资源历史记录 的时候报错. 方法是在本地磁盘项目目录上右键TortoiseSVN - Clean up 我的弹出的界面和下面一样,请勾选Break ...

  5. PowerDesigner 破解版,汉化包!

    链接:https://pan.baidu.com/s/1R_6g6keo2Y4_V0c1ImeFbA  密码:ncju

  6. POJ 1422 DAG最小路径覆盖

    求无向图中能覆盖每个点的最小覆盖数 单独的点也算一条路径 这个还是可以扯到最大匹配数来,原因跟上面的最大独立集一样,如果某个二分图(注意不是DAG上的)的边是最大匹配边,那说明只要取两个端点只要一条边 ...

  7. 基于仿生算法的智能系统I

    仿生算法仿生算法是什么? 什么是仿生? 蜜蜂会造房子,人类就学习蜜蜂盖房子的方法,之后便有了航空建造工程的蜂窝结构. 仿生是模仿生物系统的功能和行为,来建造技术系统的一种科学方法.生活仿生作品现代的飞 ...

  8. k8常用操作

    1.当delete pod失败时,使用下面命令强制删除Terminging状态下的pod kubectl delete pod xxxxxx --grace-period=0 --force 2.

  9. VS程序不显示控制台

    之所以会有这样的想法是因为,有时候我会用到一些库,这些库在使用的时候会在控制台输出一些信息,虽然这是无可厚非的事情,但是,如果我写了一个界面,这个时候当然是希望要显示什么就显示在界面上,或者就不要显示 ...

  10. UML-UML工具与UML蓝图

    1.UML应用场景 1).UML作为草图 2).UML作为蓝图. UML生成java代码(前向工程) java代码生成UML(逆向工程) 2.如果绘制了UML草图,如何在编码后更新该图形? 逆向工程, ...