IO多路转接也叫做IO多路复用,它是一种处理高并发的IO事件监控。它可以同时对大量的描述符进行监控,监控其是否具备了IO条件。
就绪:包括了读就绪事件(就是有数据到来的时候),写就绪事件(缓冲区有空闲的空间),异常事件(发生异常)。对于服务器来说,很多时候我们都是监控的读事件,对于写事件和异常事件都只会在特定的情况下使用。
select简介
系统提供了select系统调用来实现多路复用的输入输出模型。
select函数原型
头文件: #include
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
timeout:
返回值
fd_set结构体
fd_set 是一个结构体,严格来说它是一个位图,通过使用位图中对应的位来表示要监视的文件描述符。它提供了一组操作fd_set的接口, 来比较方便的操作位图.
void FD_CLR(int fd, fd_set *set); // 用来清除描述词组set中相关fd 的位
int FD_ISSET(int fd, fd_set *set); // 用来测试描述词组set中相关fd 的位是否为真
void FD_SET(int fd, fd_set *set); // 用来设置描述词组set中相关fd的位
void FD_ZERO(fd_set *set); // 用来清除描述词组set的全部位
select缺点
poll函数简介
#include
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
// pollfd结构
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
参数说明
返回值说明
poll优缺点
优点
缺点
epoll 是Linux下性能最高的IO多路转接模型。epoll 与select和poll在使用和实现上有很大区别。首先,epoll使用一组函数来完成,而不是单独的一个函数;其次,epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中,无须向select和poll那样每次调用都要重复传入文件描述符集合事件集。
epoll相关的系统调用
// #include
//创建一个epoll句柄
int epoll_create(int size);
//自从linux2.6.8之后,size参数是被忽略的.
//用完之后, 必须调用close()关闭.
//epoll的事件注册函数,在内核的eventpoll结构中添加移除,修改所监控的事件结构。
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
//第二个参数
EPOLL_CTL_ADD :注册新的fd到epfd中;
EPOLL_CTL_MOD :修改已经注册的fd的监听事件;
EPOLL_CTL_DEL :从epfd中删除一个fd
它不同于select()是在监听事件时告诉内核要监听什么类型的事件, 而是在这里先注册要监听的事件类型.
struct epoll_event 结构如下
struct epoll_event
{
__int32_t events; //epoll事件
epoll_data_t data; //用户数据
};
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
}epoll_data;
在使用epoll_ctl时,是把fd添加、修改到内核事件表中,或从内核事件表中删除fd的事件。如果是添加事件到事件表中,可以往data中的fd上添加事件events,或者不用data中的fd,而把fd放到用户数据ptr所指的内存中(因为epoll_data是一个联合体,只能使用其中一个数据),再设置events。
//它在一段时间内等待一个组文件描述符上的事件。
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
epoll的底层实现
当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关,一个是红黑树,另一个是双向链表。红黑树中存储着所有添加到epoll中的需要监控的事件,双链表中则存放着将要通过epoll_wait返回给用户的满足条件的事件。这些事件都会挂载在红黑树中,如此,重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插
入时间效率是log(n),其中n为树的高度).而所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当响应的事件发生时会调用这个回调方法.这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中.通过这种方式大大的提高了效率。
epoll的工作模式
epoll 对文件描述符的操作有两种模式:LT(level trigger:水平触发模式,default)和 ET(edge trigger:边沿触发模式)。
epoll的优缺点