I/O复用三大模型select/poll/epoll

Linux三大I/O复用函数select/poll/epoll1.select系统调用如下:

int select(int nfds, fd_set*readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);

nfds指定被监听的文件描述符的总数.它通常被设置为最大文件描述符+1,因为文件描述符是从0开始计数的.

readfds,writefds,exceptfds参数分别指向可读,可写和异常事件对应的文件描述符集合.应用程序调用select函数时,通过这三个参数传入自己感兴趣的文件描述符.

select调用返回时,内核将修改它们来通知那些文件描述符已经就绪.因此我们每次都必须重置这些集合!

fd_set结构体中,有这么一个定义:#define__FD_SETSIZE 1024这里用32个4字节整型一共1024位来分别标记这1024个文件描述符,这也限制了select所能监听的文件描述符的总数

由于位操作过于繁琐,系统还提供了一系列宏来操作fd_set结构体

FD_ZERO(fd_set *fdset);//清除fdset的所有位

FD_SET(int fd, fd_set *fdset);//设置fdset的位fd

FD_CLR(int fd, fd_set *fdset);//清除fdset的位fd

int FD_ISSET(int fd, fd_set *fdset)//测试fdset位fd是否被设置

timeout参数用来设置select函数的超时时间

struct timeval timeout

{

long tv_sec;//秒

long tv_usec;//微秒

};

如果timeout为0,那么select立刻返回

如果timeout为NULL,则直到有一个描述符就绪时select返回

如果timeout设置了相应的时间,则有描述符就绪时返回或者超时返回 超时返回0 否则返回就绪的描述符数

2.poll系统调用如下:

poll系统调用和select类似,也是在指定时间内轮询一定数量的文件描述符

int poll(struct pollfd* fds,nfds_t nfds, int timeout);

fds是一个pollfd类型的结构体数组,具体定义如下:

struct pollfd

{

int fd; //文件描述符

short events;//注册的事件

short revents;//实际发生的事件 由内核填充

};

nfds参数指定被监听的事件集合fds的大小

timeout 参数指定poll的超时时间,单位为毫秒

当timeout为0时,poll立即返回

当timeout为-1时,poll阻塞直到某个时间发生

3.epoll系统调用

epoll是Linux特有的I/O复用函数.它使用一组函数来完成任务.epoll把用户关心的文件描述符放到内核中的事件表中,从而无需像select和poll那样每次都在内核空间和用户空间拷贝文件描述符,这也是epoll为什么需要使用一个额外的文件描述符的原因:用来唯一标识内核中的这个事件表.这个文件描述符使用如下函数创建:

int epoll_create(int size);

下面的函数用来操作epoll的内核事件表

int epoll_ctl(int epfd, intop, int fd, struct epoll_event *event);

fd是要操作的文件描述符, op指定操作类型.操作类型有以下三种:

EPOLL_CTL_ADD//注册

EPOLL_CTL_MOD//修改

EPOLL_CTL_DEL//删除

主要函数上阵:

intepoll_wait(int epfd, struct epoll_event *event, int maxevents, int timeout);

epoll_wait函数如果监测到事件,就将所有的就绪事件从内核事件表(由epfd参数指定)中复制到它的第二个参数events执行的数组中,而不像select和poll的数组参数那样既用于传入用户注册的函数又用于输出内核检测到的就绪事件.这就极大地提高了应用程序索引就绪文件描述符的效率

除此之外,epoll还支持两种模式:LT水平触发模式,ET边沿触发模式

逆境磨练人、逆境是老师、逆境之苦可变甜。

I/O复用三大模型select/poll/epoll

相关文章:

你感兴趣的文章:

标签云: