(一)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)深入理解的更多相关文章

  1. IO多路复用三种方式select/poll/epoll

    select多并发socket例子: #_*_coding:utf-8_*_ __author__ = 'Alex Li' import select import socket import sys ...

  2. 解决MongoDB磁盘IO问题的三种方法

    1.使用组合式的大文档 我们知道MongoDB是一个文档数据库,其每一条记录都是一个JSON格式的文档.比如像下面的例子,每一天会生成一条这样的统计数据: { metric: "conten ...

  3. 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!

    系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...

  4. Select/Poll/Epoll异步IO

    IO多路复用 同步io和异步io,阻塞io和非阻塞io分别是什么,有什么样的区别? io模式 对于一次io 访问(以read为例),数据会先拷贝到操作系统内核的缓冲区,然后才会从操作系统内核的缓冲区拷 ...

  5. Oracle 数据库分页查询的三种方法

    一.Oracle 数据库分页查询的三种方法 1.简介 不能对 rownum 使用 >(大于或等于 1 的数值).>=(大于 1 的数值).=(不等于 1 的数值),否则无结果.所以直接用 ...

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

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

  7. IO模型之IO多路复用 异步IO select poll epoll 的用法

    IO 模型之 多路复用 IO 多路复用IO IO multiplexing 这个词可能有点陌生,但是如果我说 select/epoll ,大概就都能明白了.有些地方也称这种IO方式为 事件驱动IO ( ...

  8. Linux I/O复用中select poll epoll模型的介绍及其优缺点的比較

    关于I/O多路复用: I/O多路复用(又被称为"事件驱动"),首先要理解的是.操作系统为你提供了一个功能.当你的某个socket可读或者可写的时候.它能够给你一个通知.这样当配合非 ...

  9. Java IO 学习(二)select/poll/epoll

    如上文所说,select/poll/epoll本质上都是同步阻塞的,但是由于实现了IO多路复用,在处理聊天室这种需要处理大量长连接但是每个连接上数据事件较少的场景时,相比最原始的为每个连接新开一个线程 ...

随机推荐

  1. Object类的toString和Equals方法,以及Objects类的Equals方法

    Object类 toString()方法 public class Person { private String name; private int age; public Person() { } ...

  2. 洛谷 P5527 - [Ynoi2012] NOIP2016 人生巅峰(抽屉原理+bitset 优化背包)

    洛谷题面传送门 一道挺有意思的题,想到了某一步就很简单,想不到就很毒瘤( 首先看到这样的设问我们显然可以想到背包,具体来说题目等价于对于每个满足 \(i\in[l,r]\) 的 \(a_i\) 赋上一 ...

  3. CSP-S2021 挂分记

    赛前 数了数,这是我第五次来南航,不知道以后还有机会了(2018 NOIP, 2019CSP, 2020CSP, 2020NOIP). 上午一觉睡到 10 点,学了一下感觉很有用的 BIT 倍增,顺手 ...

  4. P3438 [POI2006]ZAB-Frogs

    P3438 [POI2006]ZAB-Frogs 给出一个不一样的解法.不需要用到斜率优化等高级算法. 下文记 \(n=w_x,m=w_y\). 首先,答案显然满足可二分性,因此二分答案 \(d\in ...

  5. 【R方差分析】蛋白质表达量多组比较

    初始数据类似: 蛋白质组数据虽不是严格的正态分布,但目前最常用的检验方法还是T检验(两组比较)和方差分析(多组比较).这个话题值得深究,这里不展开. 主要是求多个蛋白的Pvalue值或FDR,用于差异 ...

  6. Redis源码解析(1)

    在文章的开头我们把所有服务端文件列出来,并且标示出其作用: adlist.c //双向链表 ae.c //事件驱动 ae_epoll.c //epoll接口, linux用 ae_kqueue.c / ...

  7. kubernetes部署Docker私有仓库Registry

    在后面的部署过程中,有很多的docker镜像文件,由于kubernetes是使用国外的镜像,可能会出现下载很慢或者下载不下来的情况,我们先搭建一个简单的镜像服务器,我们将需要的镜像下载回来,放到我们自 ...

  8. 在前端页面中使用Markdown并且优化a标签

    近期在自己的项目中加入了对 Markdown 语法 的支持,主要用到的是markedjs这个项目.该项目托管在github上,地址为:https://github.com/markedjs/marke ...

  9. [Emlog主题] Monkey V3.0 优化修改

    原作者博客:https://blog.dyboy.cn/ Monkey V3.0 优化修改版 修改说明: 背景颜色修改(按个人喜好可自行修改,仿PCQQ午夜巴黎皮肤) 搜索框按钮样式优化,不那么突兀了 ...

  10. 【Penetration】红日靶场(一)

    nmap探查存活主机 nmap -sP 10.10.2.0/24 图片: https://uploader.shimo.im/f/cfuQ653BEvyA42FR.png!thumbnail?acce ...