epoll——IO多路复用选择器
上上篇博客讲的套接字,由于其阻塞性而导致一个服务端同一时间只能与一个客户端连接。基于这个缺点,在上篇博客我们将其设置为非阻塞实现了一个服务端同一时间可以与多个客户端相连,即实现了并发,但其同样留下了一个缺点: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,能够更快,更方便的实现多并发效果。抛开套接字,它的大体流程如下:
- 实例化一个epoll选择器
- 对epoll选择器进行注册,从而起到让操作系统去监听,参数有套接字、事件、回调函数。它会把刚生成的sock连接对象注册到select连接列表中,并交给accept函数处理 。
- 对select进行查找,若查找为空,默认是阻塞,否则返回活动的连接列表。
- 调用回调函数
- 注销选择器
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多路复用选择器的更多相关文章
- epoll—IO多路复用
1.在socket.listen()后创一个epoll对象 epoll = select.epoll() 2.将server_socket注册到epoll中 epoll.regist ...
- epoll IO多路复用(异步阻塞AIO)
epoll的异步阻塞(AIO): 用户线程创建epoll后,其实是内核线程负责扫描 fd 列表(在网络服务器上可以是socket,socket在创建后返回的也是文件描述符),并填充事件链表.但是,并不 ...
- 【python】-- IO多路复用(select、poll、epoll)介绍及实现
IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...
- IO多路复用(select、poll、epoll)介绍及select、epoll的实现
IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...
- 11 非阻塞套接字与IO多路复用(进阶)
1.非阻塞套接字 第一部分 基本IO模型 1.普通套接字实现的服务端的缺陷 一次只能服务一个客户端! 2.普通套接字实现的服务端的瓶颈!!! accept阻塞! 在没有新的套接字来之前,不能处理已经建 ...
- 利用IO多路复用,使用linux下的EpollSelector实现并发服务器
import socket import selectors # IO多路复用选择器的模块 # 实例化一个和epoll通信的选择器 epoll_selector = selectors.EpollSe ...
- 异步、非阻塞和IO多路复用总结
Nginx是并发处理框架的代表者,很多后台业务都会放在Nginx容器中运行,以实现高吞吐,而Nginx能够支持高并发也是由于使用了异步非阻塞处理模型,本文将用通俗的话讲解异步.同步.阻塞.非阻塞的区别 ...
- 网络编程基础【day10】:IO多路复用
这些名词比较绕口,理解涵义就好.一个epoll场景:一个酒吧服务员(一个线程),前面趴了一群醉汉,突然一个吼一声“倒酒”(事件),你小跑过去给他倒一杯,然后随他去吧,突然又一个要倒酒,你又过去倒上,就 ...
- Python全栈开发-Day10-进程/协程/异步IO/IO多路复用
本节内容 多进程multiprocessing 进程间的通讯 协程 论事件驱动与异步IO Select\Poll\Epoll——IO多路复用 1.多进程multiprocessing Python ...
随机推荐
- 一、REACT概述
1.前端/react概述 <从零react> 1.前端工 程概述 Web跨平台.跨浏览 器的应用开发场景 网页浏览器(Web Browser) 通过 CLI 指令去操作的 Headless ...
- Bean 注解(Annotation)配置(3)- 依赖注入配置
Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...
- Mysql :分支结构—if函数
一分支结构 1.if函数 功能:实现简单的双分支 语法: IF (表达式1,表达式2,表达式3) 执行顺序 如果表达式1成立 则if函数返回表达式2的值,否则返回表达式3的值 应用: 任何地方
- P4147 玉蟾宫(悬线法求最大子矩阵)
P4147 玉蟾宫 悬线法 ,\(l_{i,j},r_{i,j},up_{i,j}\) 分别表示 \((i,j)\) 这个点向左,右,上能到达的远点.然后面积就很好办了.具体实现见代码. 然而,还有更 ...
- PHP ~ 原生语法 ~ 根据从数据库查询数据之后快速输出 某个属性的值到 到页面
一,根据 id 来查询单个的数据 <?php require_once '../../conn.php'; $sql = "select * from blogarticle wher ...
- 语句:{% url menu.url_name %}的作用
语句: {% url menu.url_name %} 表示跳转,上面的menu.url_name意思是menu表的url_name字段 如果menu表的url_name字段的值是sales_dash ...
- react-native-tab-view 导航栏切换插件讲解
首先引入插件 yarn add react-native-tab-view 如果用的原生环境要安装另外几个插件 yarn add react-native-reanimated react-nativ ...
- Vue 项目de一些准备工作
1.安装node,同时也会自动安装npm,npm是node的一种包安装工具. 2.准备一个git,可以用来管理代码. 3.打开vue官网,可以使用vue-cli脚手架工作. 这里介绍一个element ...
- 从1到n整数中1的个数
[问题]求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了.A ...
- Java Web应用的加载过程
在介绍Spring IoC和MVC的加载前,用这篇小文章简单地记录下,最简单的web应用的加载过程. 一.从最简单的web应用出发 使用Eclipse直接创建一个Dynamic Web Project ...