IO复用

IO复用:使得程序能同时监听多个文件描述符

select:

select在一段指定的时间内,监听用户感兴趣的文件描述符的 读、写、异常事件。

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

当调用了select之后整个进程就会被block。同时kernel会监听select负责的所有的socket.如果
相关的时间就绪就会返回。

但是select只能处理 读、写、异常事件,不能处理更多的事件。
而且内核是对fd_set集合在线修改,下次调用不得不重置相应的集合。。。


poll:

int poll(struct pollfd* fds,....);

与select不同的是poll将 文件描述符和时间集合都定义在了 结构体中。并且注册事件和实际发生事件
被分开了。

struct pollfd
{ 
    int fd;
    short events;   //注册事件
    short revents;   //实际发生事件
}

于是每次内核修改的是revents,无需重置pollfd了。


epoll:

epoll将用户关心的文件描述符放在内核的一个事件表中,从而无须每次重复传递。但需要一个额外的文件描述符
来标志内核中的时间表

epoll_create(int size)             //创建一个事件表
epoll_ctl()                          //给文件符指定操作类型(注册xxx上的xxx事件...)
epoll_wait()                         //等待事件

三种方法差异:

select和poll都只能工作在相对低效的LT模式中,epoll则能在ET模式中并支持EPOLLONESHOT。
select和poll采用的轮询的方式,每次调用都要扫描整个事件表O(n),而epoll采用的是回调,如果检测到
就绪的,回调函数就将对应时间插入内核就绪队列中,最后直接拷贝出来O(1)。
如果触发频繁,epoll的效率不一定高。所以epoll适合连接数量多,活动少的情况。


LT和ET:

1.LT(电平模式):
当epoll_wait检测到事件发生,程序可以不立即处理,再次调用还会出现此事件,直到事件被处理。

2.ET(边沿触发):
当epoll_wait检测到事件发生,程序必需立即处理,因为再次调用不会出现。


EPOLLONESHOT事件:

即便使用ET,一个事件还是可能被多次触发。
比如一个线程读取完某个socket上的数据并进行处理时,socket又出现新的数据可读。。。
此时另一个线程会被唤醒来处理这个。
如果希望任意时刻一个socket只被一个线程处理,可以使用epoll的EPOLLONESHOT

参考:

linux高性能服务器编程

转载于:https://www.cnblogs.com/Przz/p/6590857.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值