IO复用的三种方法(select,poll,epoll)深入理解
(一)IO复用是Linux中的IO模型之一,IO复用就是进程告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程处理,从而不会在单个IO上阻塞了,Linux中,提供了select、poll、epoll三种接口来实现IO复用
(二)select:
缺点:
单个进程能够监视的文件描述符的数量存在最大限制,通常是1024。由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;
内核/用户空间内存拷贝,select需要大量的句柄数据结构,产生巨大开销;
select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生事件;
select的触发方式为水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么下次select调用还会将这些文件描述符通知进程;
(三)poll:
使用链表保存文件描述符,没有了文件描述符的限制,但其他的三个缺点依然存在
(四)epoll:
上面所说的select缺点都不存在,epoll使用了一个文件描述符管理了多个文件描述符。拿select模型为例,假设我们服务器需要支持100万个并发链接,则在_FD_SETSIZE为1024的情况下,则我们至少需要开辟1K个进程才能实现100万的并发连接,除了进程上下文切换的时间消耗,从内核到用户空间的拷贝,数据轮询,是系统难以承受的,因此,基于select模型的服务器程序,要达到10万级别的并发访问,是一个很难完成的任务。
epoll的设计与select完全不同,epoll通过在Linux内核申请一个简易的文件系统(文件一般使用什么数据结构实现?B+树),把原先的select/epoll调用分为3个部分:
调用epoll_create()建立了一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)
调用epoll_ctl()向epoll对象添加这100万个连接的套接字(ip地址+端口号)
调用epoll_wait()收集发生事件的连接
epoll机制实现思路:
当某一进程调用epoll_create()方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用密切相关
struct eventpoll
{
//............
//红黑树的根节点,这棵树的每个节点代表着用户告诉内核需要监控的文件描述符
struct rb_root rbr;
//调用epoll_wait()函数后满足条件的文件描述符会被添加到rdlist中,也是后期返回用户的事件
struct list_head rdlist;
};
每一个epoll对象都有一个独立的eventpoll结构体,用于存放epoll_ctl()方法向epoll对象中添加进来的事件,这些事件都会存放在这颗红黑树中,红黑树的增删查改的效率为logn,其中n为数的高度。
而所有添加到epoll对象中的事件都会与设备(网卡)驱动程序建立回调关系,当相应的事件发生时会调用这个回调方法,这个回调方法在内核中叫做ep_poll_back,它会将发生的事件添加到rdlist双链表中。
在一个epoll对象中,对于每一个事件,都会建立一个epitem结构体如下:
struct epitem
{
struct rb_node rbn;//红黑树节点
struct list_head rdllink;//双向链表节点
struct epoll_filefd ffd;//事件句柄信息
struct eventpoll *ep;//指向其所属的event对象
struct epoll_event event;//期待发生的事件类型
};
当调用epoll_wait()检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可,如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。
从上面的讲解可知:通过红黑树和双链表数据结构并结合回调机制,才有如此高效的epoll
epoll在使用ET模式的时候一定是非阻塞的,如果是阻塞的话,一个任务监控多个文件描述符时,当一个描述符阻塞就会使其他的描述符所在的任务失败(饿死)
————————————————
版权声明:本文为CSDN博主「_kean」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/C1029323236/java/article/details/90551959
IO复用的三种方法(select,poll,epoll)深入理解的更多相关文章
- IO多路复用三种方式select/poll/epoll
select多并发socket例子: #_*_coding:utf-8_*_ __author__ = 'Alex Li' import select import socket import sys ...
- 解决MongoDB磁盘IO问题的三种方法
1.使用组合式的大文档 我们知道MongoDB是一个文档数据库,其每一条记录都是一个JSON格式的文档.比如像下面的例子,每一天会生成一条这样的统计数据: { metric: "conten ...
- 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!
系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...
- Select/Poll/Epoll异步IO
IO多路复用 同步io和异步io,阻塞io和非阻塞io分别是什么,有什么样的区别? io模式 对于一次io 访问(以read为例),数据会先拷贝到操作系统内核的缓冲区,然后才会从操作系统内核的缓冲区拷 ...
- Oracle 数据库分页查询的三种方法
一.Oracle 数据库分页查询的三种方法 1.简介 不能对 rownum 使用 >(大于或等于 1 的数值).>=(大于 1 的数值).=(不等于 1 的数值),否则无结果.所以直接用 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- IO模型之IO多路复用 异步IO select poll epoll 的用法
IO 模型之 多路复用 IO 多路复用IO IO multiplexing 这个词可能有点陌生,但是如果我说 select/epoll ,大概就都能明白了.有些地方也称这种IO方式为 事件驱动IO ( ...
- Linux I/O复用中select poll epoll模型的介绍及其优缺点的比較
关于I/O多路复用: I/O多路复用(又被称为"事件驱动"),首先要理解的是.操作系统为你提供了一个功能.当你的某个socket可读或者可写的时候.它能够给你一个通知.这样当配合非 ...
- Java IO 学习(二)select/poll/epoll
如上文所说,select/poll/epoll本质上都是同步阻塞的,但是由于实现了IO多路复用,在处理聊天室这种需要处理大量长连接但是每个连接上数据事件较少的场景时,相比最原始的为每个连接新开一个线程 ...
随机推荐
- MYSQL免安装
MYSQL免安装 本文使用mysql 8.0.22进行演示 一.MYSQL 下载 [x] 官网下载:地址:https://dev.mysql.com/downloads/mysql/ [x] 百度云盘 ...
- 软虹sdk基本使用
虹软SDK的简单使用 Java实现人脸识别,但是又不会自己实现算法,找SDK时发现了虹软.虹软SDK具有免费.识别率高等优点,然后到网上搜这个SDK的教程,没搜到,就自己探索,发现它自带的官方文档其实 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- 【5】蛋白质组学鉴定定量软件之PD
目录 1.简介 2.安装与配置 3.分析流程 4.结果 1.简介 PD全称Proteome Discoverer,是ThermoFisher在2008年推出的商业Windows软件,没错,收费,还不菲 ...
- R语言与医学统计图形-【9】过渡函数qplot
ggplot2绘图系统 基础绘图包向ggplot2过渡--qplot 绘图理念的不同: 基础绘图包是先铺好画布,再在这张画布上作图(常规思维): ggplot2打破常规,采用图层叠加的方法. qplo ...
- nginx_rewrite
介绍: 和apache等web服务软件一样,rewrite的组要功能是实现RUL地址的重定向.Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的.默认 ...
- SQL-关联表查询(连表查询)
0.例如:select * from T1,T2 where T1.a=T2.a 1.连表查询 <=> join(inner join)内连接查询 数据源: Persion表: ...
- Applescript快速入门及OmniFocus每日md报告开发
本篇主要记录 Applescript 基础语法,以及利用 applescript 生成 omnifocus 每日报告 从 windows 转换到 macos,最近一直在不断折腾,这两天浏览 githu ...
- 一起手写吧!Promise!
1.Promise 的声明 首先呢,promise肯定是一个类,我们就用class来声明. 由于new Promise((resolve, reject)=>{}),所以传入一个参数(函数),秘 ...
- @Value("#{}")与@Value("${}")
开发过程中,有些配置信息是根据环境的不同而有不同的值.这个时候,我们需要获取配置文件中的值或者spring容器中的值,可以通过@value注解获取相关的值. @Value("#{}" ...