深入理解select、poll和epoll

I/o复用函数:Select,poll&epoll 能同时监听多个文件描述符
多进程,多线程每一个执行序列在同一个时刻只能处理一个sockfd(监听,链接)
select、poll和epoll能同时监听多个文件描述符,他们等待指定时间后,直到一个或多个文件描述符上有事件发生返回,返回值是就绪的文件描述负数量,返回0表示没有事件发生。
I/O复用:同一进程或线程,同时监听多个socket,当socket上有事件时,程序才接受数据
监听套接字socketfd上有描述符——>accept()
链接套接字c上有描述符——>receive()
fd*set 容纳描述符的数组

Select

向内核传递描述符:每轮循环都要重新拷贝到内核空间
内核的实现: 内核轮训检查每个描述符上有没有事件
I/0函数返回后,遍历所有的描述符,找到就绪的

Int select(int nfds,fd_set *read,fd_set *write,fd_set *except,struct timeval *timeout)

n:n个描述符上有数据
nfds:监听的最大文件描述符+1;
read ,write ,except:select监听文件描述符上的可读,可写,异常事件,若对条件不感兴趣,则设置为NULL
Int n=select(fd+1,fdset,NULL,NULL,&tv)
返回值:0 超时 -1 出错 >0 就绪文件描述符的个数

Struct timeval* timeout

判断超时——>&tv:时间未到,输入数据,则阻塞

Struct timeval
{
long tv_sec;    //秒数
long tv_usec;   //微秒
}

Struct fd_set 最多可容纳1024位描述符
{
Long int fd_sets[32];
}

Poll:

将要关注的描述符,事件放在同一个结构体中,且关注的描述符比select多
向内核传递描述符:每轮循环都要重新拷贝到内核空间
内核的实现:内核轮询检查每个描述符上有没有事件
I/0函数返回后,遍历所有的描述符,找到就绪的
Int poll(struct pollfd *fds,unsigned int nfds,int timeout)
返回值:0 超时 -1 出错 >0 就绪文件描述符的个数
fds:数组,数组中记录所有监听文件描述符和关注的事件类型
nfds:数组元素个数
timeout:超时时间,单位毫秒,-1 永远阻塞 0 立即返回
Timeout 若为负数,则表示无限超时,使poll()一直挂起直到一个指定事件发生
Timeout 若为0,表示poll函数调用立即返回并列出准备好的io文件的描述符,但不等待其他事件。

Struct pollfd
{
Int fd;          //文件描述符
Short events;    //内核想关注的进程
Short revents;   //实际发生的事件
}

每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个文件描述符,致使poll()监视多个文件描述符,events域中请求的任何事件都可能在revents域中返回。

epoll:

#include<sys/epoll.h>
向内核传递描述符:每个文件描述符都拷贝一次到内核空间
内核的实现:在每个文件描述符上设置回调函数,有数据就绪,调用回调函数添加到就绪队列
I/0函数返回,直接返回就绪的文件描述符,不用遍历所有描述符
Int epoll_creat(int size) //创建一个额外的文件描述符,用来唯一标识内核中的事件表,size指的是监听的数目,创建好文件句柄后,它占用一个fd值,使用完epoll()后,必须调用close关闭,否则导致fd耗尽。返回内核事件表的标识符fd,

Int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event)

epfd:内核事件表的id即要操作的文件描述符,epoll_create的返回值
op:指定操作类型
EPOLL_CTL_ADD, 往时间表中注册fd上的事件
EPOLL_CTL_MOD,修改fd上的注册事件
EPOLL_CTL_DEL,删除fd上的注册事件
event:指定事件 是epoll_event结构体指针类型

Struct epoll_event
{
Int events;  //epoll事件
epoll_data_t data;  //用户事件
};

events,描述事件类型
epoll_data_t 一个联合体,有4个成员,使用最多的是fd

Int epoll_wait(int epfd,struct epoll_event *event,int maxevents,int timeout)

成功,则返回就绪的文件描述符的个数,失败,返回-1,并设置error;
timeout 超时时间;
Maxevents 指定最多监听多少时间,必须大于0
epoll_wait函数若监测到数据,就将所有就绪的事件从内核事件表中复制到他的第二个参数events指向的数组中,这个数组中值用于输出epoll_wait监测到的就绪事件,而select和poll的数组参数既用于传入用户注册的事件,又用于输出内核监测到的就绪事件。epoll大大的提高了应用程序索引就绪文件描述符的效率。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值