专注分享Linux后台服务器开发,包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等


1.Select

首先先分析一下select函数

int select(
int maxfdp1,
fd_set *readset,
fd_set *writeset,
fd_set *exceptset,
const struct timeval *timeout
);

【参数说明】

int maxfdp1 指定待测试的文件描述字个数,它的值是待测试的最大描述字加1。

fd_set *readset , fd_set *writeset , fd_set *exceptset

fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即 文件句柄。中间的三个参数指定我们要让内核测试读、写和异常条件的文件描述符集合。 如果对某一个的条件不感兴趣,就可以把它设为空指针。

const struct timeval *timeout timeout告知内核等待所指定文件描述符集合中的任 何一个就绪可花多少时间。其timeval结构用于指定这段时间的秒数和微秒数。

【返回值】

int 若有就绪描述符返回其数目,若超时则为0,若出错则为-1

select运行机制

select()的机制中提供一种fd_set的数据结构,实际上是一个long类型的数组,每一 个数组元素都能与一打开的文件句柄(不管是Socket句柄,还是其他文件或命名管道或 设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根 据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一Socket或文件 可读。

从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还 多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select 以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注 册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程 内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达 到这个目的。

select机制的问题

每次调用select,都需要把fd_set集合从用户态拷贝到内核态,如果fd_set集合很 大时,那这个开销也很大

同时每次调用select都需要在内核遍历传递进来的所有fd_set,如果fd_set集合很 大时,那这个开销也很大

为了减少数据拷贝带来的性能损坏,内核对被监控的fd_set集合大小做了限制,并且 这个是通过宏控制的,大小不可改变(限制为1024).

2.Poll

poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是 进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。 也就是说,poll只解决了上面的问题3,并没有解决问题1,2的性能开销问题。

下面是pll的函数原型:

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
typedef struct pollfd {int fd;                         // 需要被检测或选择的文件描述符short events;                   // 对文件描述符fd上感兴趣的事件short revents;                  // 文件描述符fd上当前实际发生的事件
} pollfd_t;

poll改变了文件描述符集合的描述方式,使用了pollfd结构而不是select的fd_set 结构,使得poll支持的文件描述符集合限制远大于select的1024

【参数说明】

struct pollfd *fds fds是一个struct pollfd类型的数组,用于存放需要检测其状 态的socket描述符,并且调用poll函数之后fds数组不会被清空;一个pollfd结构 体表示一个被监视的文件描述符,通过传递fds指示 poll() 监视多个文件描述符。其 中,结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域,结构 体的revents域是文件描述符的操作结果事件掩码,内核在调用返回时设置这个域

nfds_t nfds 记录数组fds中描述符的总数量

【返回值】

int 函数返回fds集合中就绪的读、写,或出错的描述符数量,返回0表示超时,返回 -1表示出错;

Epoll

epoll在Linux2.6内核正式提出,是基于事件驱动的I/O方式,相对于select来说, epoll没有描述符个数限制,使用一个文件描述符管理多个描述符,将用户关心的文件 描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一 次。

Linux中提供的epoll相关函数如下:

int epoll_create(int size);
int epoll_ctl(
int epfd,
int op, int fd,
struct epoll_event *event
);
int epoll_wait(
int epfd,
struct epoll_event * events,
int maxevents,
int timeout
);

1).epoll_create 函数创建一个epoll句柄,参数size表明内核要监听的描述符数量。 调用成功时返回一个epoll句柄描述符,失败时返回-1。

2).epoll_ctl 函数注册要监听的事件类型。四个参数解释如下:

epfd 表示epoll句柄

op 表示fd操作类型,有如下3种

EPOLL_CTL_ADD 注册新的fd到epfd中

EPOLL_CTL_MOD 修改已注册的fd的监听事件

EPOLL_CTL_DEL 从epfd中删除一个fd

fd 是要监听的描述符

event 表示要监听的事件

epoll_event 结构体定义如下:

struct epoll_event {__uint32_t events;  /* Epoll events */epoll_data_t data;  /* User data variable */
};
typedef union epoll_data {void *ptr;int fd;__uint32_t u32;__uint64_t u64;
} epoll_data_t;

3). epoll_wait 函数等待事件的就绪,成功时返回就绪的事件数目,调用失败时返回 -1,等待超时返回 0。

⑴epfd 是epoll句柄

⑵events 表示从内核得到的就绪事件集合

⑶maxevents 告诉内核events的大小

⑷timeout 表示等待的超时事件

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用 IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃 的情况下的系统CPU利用率。原因就是获取事件的时候,它无须遍历整个被侦听的描述 符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。

epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供 了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少 epoll_wait/epoll_pwait的调用,提高应用程序效率。

⑴水平触发(LT):默认工作模式,即当epoll_wait检测到某描述符事件就绪并 通知应用程序时,应用程序可以不立即处理该事件;下次调用epoll_wait时,会 再次通知此事件

⑵边缘触发(ET): 当epoll_wait检测到某描述符事件就绪并通知应用程序时, 应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次 通知此事件。(直到你做了某些操作导致该描述符变成未就绪状态了,也就是说边 缘触发只在状态由未就绪变为就绪时只通知一次)。

LT和ET原本应该是用于脉冲信号的,可能用它来解释更加形象。Level和Edge指的就 是触发点,Level为只要处于水平,那么就一直触发,而Edge则为上升沿和下降沿的 时候触发。比如:0->1 就是Edge,1->1 就是Level。

ET模式很大程度上减少了epoll事件的触发次数,因此效率比LT模式下高。


关注我,每天分享Linux后台服务器开发,包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等

poll函数_如何理解IO多路复用的三种机制Select,Poll,Epoll?相关推荐

  1. IO多路复用的三种机制Select,Poll,Epoll

    目录 1. IO多路复用 2.操作系统基础概念 3.Select 4.Poll 5.Epoll 6.总结 1. IO多路复用 I/O多路复用(multiplexing)的本质是通过一种机制(系统内核缓 ...

  2. io多路复用的原理和实现_彻底理解 IO 多路复用实现机制

    本文作者:何建辉(公众号:org_yijiaoqian) 点赞再看,养成习惯,微信搜一搜[一角钱技术]关注更多原创技术文章.本文 GitHub org_hejianhui/JavaStudy已收录,有 ...

  3. io多路复用的原理和实现_IO多路复用的三种机制:select 、poll 、epoll

    目录 概述 IO多路复用本质 IO多路复用的优势 IO多路复用Select机制 IO多路复用Poll机制 IO多路复用Epoll机制 select,poll,epoll机制区别总结 php7进阶到架构 ...

  4. poll函数_I/O--多路复用的三种机制Select,Poll和Epoll对比

    I/O多路复用(multiplexing)的本质是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作 ...

  5. 【面试】彻底理解 IO多路复用

    目录 1.什么是IO多路复用? 2.为什么出现IO多路复用机制? 3.IO多路复用的三种实现方式 4.select函数接口 5.select使用示例 6.select缺点 7.poll函数接口 8.p ...

  6. 什么是IO多路复用,理解IO多路复用

    什么是IO多路复用? IO 多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄: 一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作: 没有文件句柄就绪就会阻塞应用程序,交出CPU. ...

  7. Python:通过一个小案例深入理解IO多路复用

    通过一个小案例深入理解IO多路复用 假如我们现在有这样一个普通的需求,写一个简单的爬虫来爬取校花网的主页 import requests import timestart = time.time()u ...

  8. 5分钟理解Iass Pass SasS三种云服务区别

    5分钟理解Iass Pass SasS三种云服务区别 其实搞懂这个问题也不难,我们可以把云计算理解成一栋大楼,而这栋楼又可以分为顶楼.中间.低层三大块. 那么我们就可以把Iass(基础设施).Pass ...

  9. 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...

最新文章

  1. ISAPI在IIS7上的配置
  2. Java--------------Mysql中时间按要求查询
  3. php微信扫码支付报错,(转)微信调用扫码和支付功能是都报错 the permission value is offline verifying...
  4. CSP认证201612-4 压缩编码[C++题解]:区间dp、huffman树、石子合并
  5. java压缩对象_Java 对象指针压缩
  6. 树莓派4支持多大tf卡_陪你一起玩树莓派-系统安装
  7. 全局bigdecimal反序列化转String返回数据
  8. [Swift]LeetCode311. 稀疏矩阵相乘 $ Sparse Matrix Multiplication
  9. linux-mount-iso
  10. S5P6818开发板移植OV5640摄像头
  11. 张老师的生日是哪一天?
  12. 强烈推荐提升自我的30个好习惯
  13. 第三十四篇 源极跟随器
  14. mysql 百分比两位小数_SQL中如何让百分比后面保留2位小数?
  15. 02_计算机网络笔记-网络拓扑-交换机-VLAN
  16. java string 去掉某个字符_JAVA String 如何去掉指定字符
  17. verify_area
  18. 奇兔recovery卡刷教程_vivo X6(双4G)刷Recovery教程
  19. 直面项目管理问题 促进项目精细化管理
  20. windows10快速打开回收站(Recycle Bin)

热门文章

  1. UI实用|素材APP启动图标设计模板
  2. C++共享内存类封装
  3. APIC ID 的通用七级解释与概念性六级拓扑:APICID
  4. Linux虚拟化KVM-Qemu分析(十)之virtio驱动
  5. zlib-1.2.11手册
  6. 一种基于红黑树的定时器
  7. iphone11右上角信号显示_iOS 11信号显示栏变了!这意味着啥?
  8. git 如何忽略掉文件夹_#PY小贴士# 我的git仓库为什么每次提交都有很多改动?
  9. 笔记本电脑如何强制关机_笔记本按电源按钮不能关机只是关闭屏幕的解决办法...
  10. Flink之Redis的安装及RedisSink的用法