IO多路复用(一)-- Select、Poll、Epoll

 在上一篇博文中提到了五种IO模型,关于这五种IO模型可以参考博文IO模型浅析-阻塞、非阻塞、IO复用、信号驱动、异步IO、同步IO,本篇主要介绍IO多路复用的使用和编程。

IO多路复用的概念

多路复用是一种机制,可以用来监听多种描述符,如果其中任意一个描述符处于就绪的状态,就会返回消息给对应的进程通知其采取下一步的操作。

IO多路复用的优势

当进程需要等待多个描述符的时候,通常情况下进程会开启多个线程,每个线程等待一个描述符就绪,但是多路复用可以同时监听多个描述符,进程中无需开启线程,减少系统开销,在这种情况下多路复用的性能要比使用多线程的性能要好很多。

相关API介绍

在linux中,关于多路复用的使用,有三种不同的API,select、poll和epoll

Select介绍

select的使用需要引入sys/select.h头文件,API函数比较简单,函数原型如下:

int select (int __nfds, fd_set *__restrict __readfds,            fd_set *__restrict __writefds,            fd_set *__restrict __exceptfds,            struct timeval *__restrict __timeout);

fd_set

其中有一个很重要的结构体fd_set,该结构体可以看作是一个描述符的集合,可以将fa_set看作是一个位图,类似于操作系统中的位图,其中每个整数的每一bit代表一个描述符,。

举个简单的例子,fd_set中元素的个数为2,初始化都为0,则fd_set中含有两个整数0,假设一个整数的长度8位(为了好举例子),则展开fd_set的结构就是 00000000 0000000,如果这个时候添加一个描述符为3,则对应fd_set编程 00000000 00001000,可以看到在这种情况下,第一个整数标记描述符0~7,第二个整数标记8~15,依次类推。

fd_set有四个关联的api

void FD_ZERO(fd_set *fdset) //清空fdset,将所有bit置为0 void FD_SET(int fd, fd_set *fdset) //将fd对应的bit置为1 void FD_CLR(int fd, fd_set *fdset) //将fd对应的bit置为0 void FD_ISSET(int fd, fd_set *fdset) //判断fd对应的bit是否为1,也就是fd是否就绪

select函数中存在三个fd_set集合,分别代表三种事件,__readfds表示读描述符集合,__writefds表示读描述符集合,__exceptfds表示读描述符集合,当对应的fd_set = NULL时,表示不监听该类描述符。

__nfds

__nfds是fd_set中最大的描述符+1,当调用select的时候,内核态会判断fd_set中描述符是否就绪,__nfds告诉内核最多判断到哪一个描述符。

timeval

struct timeval {     long tv_sec;    //秒     long tv_usec;   //微秒 }

参数__timeout指定select的工作方式:

  • __timeout= NULL,表示select永远等待下去,直到其中至少存在一个描述符就绪
  • __timeout结构体中秒或者微妙是一个大于0的整数,表示select等待一段固定的事件,若该短时间内未有描述符就绪则返回
  • __timeout= 0,表示不等待,直接返回

函数返回

select函数返回产生事件的描述符的数量,如果为-1表示产生错误

值得注意的是,比如用户态要监听描述符1和3的读事件,则将readset对应bit置为1,当调用select函数之后,若只有1描述符就绪,则readset对应bit为1,但是描述符3对应的位置为0,这就需要注意,每次调用select的时候,都需要重新初始化并赋值readset结构体,将需要监听的描述符对应的bit置为1,而不能直接使用readset,因为这个时候readset已经被内核改变了。

Poll介绍

select中,每个fd_set结构体最多只能标识1024个描述符,在poll中去掉了这种限制,使用poll需要引入头文件sys/poll.h,poll调用的API如下:

int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);

pollfd

struct pollfd {     
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信