多路I/O复用的三个函数select、poll、epoll

一、select

1.函数原型

函数原型
#include<sys/select.h>
select(int maxfdpl,
fd_set *restrict readfds,fd_set *restrict writefds,fd_set*restrict exceptfds,
struct timeval *restrict tvptr
);
//maxfdpl:最大文件描述符编号值加1.可以设定为FD_SETSIZE,指定最大描述符数(经常是1024),大多数程序只使用3~10个描述符

//中间三个参数是指向描述符的指针,每个描述符集存储在fd_set数据类型中。
//对于fd_set数据类型,唯一可以进行的处理是:分配一个这种类型的变量,将这种类型的一个变量值给·同类型的一个变量,或者可以使用以下四个函数中的一个:
#include<sys/select.h>
FD_ISSET(int fd,fd_set *fdset);//测试fdset描述符集中的fd是否打开(比如可读、可写)
FD_CLR(int fd,fd_set *fdset);//清除fd
FD_SET(int fd,fd_set *fdset);//开启fd
FD_ZERO(fd_set *fdset);//将fd_set集中的所有变量清0

//tvptr
//tvptr==NULL,永远等待;
//tvptr->tv_sec==0&&tvptr->tvusec==0,根本不等嗲;
//tvptr->tv_sec!=0||tv->tv_usec!=0,等待指定的秒数和微秒数.

返回值:
-1:出错
0:没有描述符准备好
正返回值:已经准备好的描述符数

注:如果在一个描述符碰见了文件尾端,select会认为该描述符是可读的

2. 使用步骤

使用步骤
fd_set rset;//声明一个描述符集
int fd;//描述符
FD_ZERO(&rset);//将声明的描述符集清0
FD_SET(fd,rset);
FD_SET(SUDIN_FILENO,rset);

//从select返回时,可以用FD_ISSET测试该集中的一个给定位是否仍处于打开状态
if(FD_ISSET(fd,&rset)){
...
}

二、poll

1. 函数原型

参考:epoll使用详解:epoll_create、epoll_ctl、epoll_wait、close

#include<poll.h>
int poll(struct pollfd fdarray[],nfds_t nfds,int timeout);//返回值:准备就绪的描述符数目,若超时,返回0,如出错,返回-1

struct pollfd{
int fd;//文件描述符
short events;//对文件描述符感兴趣的事件
shor revents;//发生在fd上的事件
}

//fdarray数组中的元素由nfds指定

//timeout==-1 在 <stropts.h>定义为INFTIM;
//timeout==0,不等待;
//timeout>0,等待timeout毫秒

使用select和poll可以实现异步形式的通知,关于描述符的状态,系统并不告诉我们描述符的状态,我们需要进行查询

三、epoll

1. 函数原型

int epoll_create(int size);//创建一个epool对象,在epoll文件系统中给这个句柄分配资源
int epoll_ctl(int epfd,int op,int fd,struct epollevent *event);//想epoll对象中添加套接字
int epoll-wait();//收集发生事件的连接

2. 详解

  1. epoll_create()
    当函数调用epoll_create方法时,linux内核会创建一个eventpoll结构体,这个结构体里面由两个成员与epoll的使用方式密切相关。
struct eventpoll{
//红黑树的根节点,这颗树中存储着所有添加到epoll的事件
//也就是epoll监控的事件
stuct rb_root rbr;

//双向链表rdllist,保存着将要通过epoll_wait返回给用户的,满足条件的事件
struct list_head rdllist;
}

解析:
我们调用epoll_create时,内核会帮我们在epoll文件系统里建立一个file结点,在内核cache里建立一个红黑树存储以后epoll_ctl传来的socket,建立一个rdllist双向链表用于存储准备就绪的事件,当epoll_wait调用时,仅仅观察这个rdllist双向链表即可,所以epoll非常高效。
rdllist如何得到事件:所有添加到epoll的事件都会与设备驱动程序建立回调关系,也就是说相应的事件发生时会调用这个回调方法,这个回调方法在内核中叫做ep_poll_callback,这个回调方法会把事件放到rdllist双向链表中。
epoll的LT模式(水平触发)和ET模式(边缘触发):LT,只要有数据就会返回。ET,只有数据到来才会触发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值