IO复用技术在编写网络程序经常需要用到,对他的需求可分为多种情况,具体就不讨论了。linux下实现IO复用主要有三种系统调用:select、poll和epoll。
1、select API
<sys/select.h>
int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
nfds参数指定被监听文件描述符的总数。后面三个参数分别指向可读、可写和异常等事件对应的文件描述符集合,timeout参数用来设置select函数超时时间。
2、poll API
<poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
fds参数是一个pollfd结构类型的结构体,他指定感兴趣的文件描述符上放生的可读、可写和异常等事件。
struct pollfd
{
int fd; //文件描述符
short events; // 注册事件
short revents; //实际发生的事件,由内核填充
}
nfds参数指定被监听时间集合fds的大小。
timeout参数指定poll的超时时间。
3、epoll API
epoll是Linux特有的IO复用函数,epoll使用一组函数来完成任务,而不是单个函数。epoll把用户关心的文件描述符上的事件放在内核的一个事件表中,不像select和poll每次调用都要重复传入文件描述符集或事件集。epoll使用一个额外的文件描述符来唯一标示内核中的这个事件表。该文件描述符用如下函数创建:
<sys/epoll.h>
int epoll_create(int size)
该函数返回的文件描述符将用作其他所有epoll系统调用的第一个参数,一指定所访问的内核事件表。下面函数用来操作epoll的内核事件表:
<sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
fd指定要操作的文件描述符,op指定操作类型(注册、修改和删除),event指定事件。
epoll_wait函数,在一段超时时间内等待一组文件描述符上的事件,原型如下:
<sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
该函数成功返回时返回就绪文件描述符的个数。timeout为超时时间。maxevents为最多监听多少个事件。events数组存放是是就绪的事件,而不像select和poll的数组参数那样既用于传入用户注册事件,有用于输出内核检测的就绪事件。这就大大提高了应用程序索引就绪文件描述符的效率。
4、它们的区别