关于poll与epoll

一:poll

1.poll与select相同,都是在指定时间内轮询一定数量的文件描述符,测试是否有就绪事件

2.poll的参数int (struct pollfd* fds,nfds_t nfds,int timeout)

fds是一个pollfd结构体类型的数组

pollfd类型三个参数:fd表示关注的文件描述符;

short events是告诉poll监听fd上的那些事件,是一系列事件的按位或,因为short有16位所以有16个事件;

short revents由内核修改,以通知应用程序fd上实际发生了哪些事情

nfds参数是一个无符号长整型数据,指定被监听事件集合fds'的大小

二:epoll

1.epoll与select和poll相比,epoll使用一组函数来完成任务而不是单个函数。其次epoll把用户关心(注册的文件描述符)的文件描述符放在一个内核事件表中,从而无需像select和poll那样每次调用都要重复传入文件描述符集或事件集。但是epoll需要使用一个额外的文件描述符,来唯一标识内核中的这个事件表,该文件描述符通过epoll_create(int size)来创建,参数的作用是给内核提示事件表需要多大

2.操作epoll的内核事件表的函数 int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);

Epfd:内核事件表的fd   fd:要操作的文件描述符  op:指定操作类型,有三种往事件表上注册fd上的事件,修改fd上的注册事件,删除fd上的注册事件

Event 指定事件struct epoll_event中的两个成员 是:epoll事件和一个epoll_data_t(union联合体)类型的用户数据

epoll_data_t中有一个fd,它指定事件所从属的目标文件描述符

epoll事件其余与poll相同但是比poll多了两个EPOLLET(ET模式注册的事件)和EPOLLONESHOT

3.epoll_wait:int epoll_wait(int epfd,struct epoll_event* events,int maxenevts,int timeout)

函数成功时返回就绪的文件描述符的个数,失败返回-1,并设置error

maxevents指定最多监听多少个事件,必须大于0

*events:数组,接收就绪fd

如果epoll_wait检测到事件就将所有就绪的事件从内核事件表中复制到第二个参数events中。这个数组只用于输出epoll_wait检测到的就绪事件,而不像selelct和poll的数组参数那样既用于传入用户注册事件又用于输出内核检测到的就绪事件,这就极大的提高了应用程序索引就绪文件描述符的效率。

4.LT普遍的默认水平触发模式 ET高效的边缘触发:当往epoll内核事件表中注册一个文件描述符上的EPOLLET事件时epoll将以ET模式来操作该文件描述符。

LT模式是当epoll_wait检测到它上面有事件发生并将此通知应用程序时应用程序可以不立即处理该事件,这样当下一次调用epoll_Wiat时,epoll_wait还会再次向应用程序通告此事,直到该事件被处理。而ET,当epoll_wait检测到并通知应用程序后,应用程序必须立即处理该事件,因为后续epoll_wait将不会在向应用层程序通知该事件。ET在很大程度上降低了同一个epoll事件被重复触发的次数,因此比LT模式要高效。

5.使用ET模式的文件描述符都应该是非阻塞的,如果是阻塞的,那么读或者写操作将因为没有后续的的事件而一直处于阻塞状态。

6.EPOLLONESHOT即使使用ET模式,一个socket上的某个事件还是可能被触发多次。在并发时就会引起问题。比如一个线程/进程 ,读取完某个socket上的数据后开始处理这些数据,而在处理数据时socket上又有新的数据可读(EPOLLIN)再次触发,此时另外一个线程被唤醒来读取这些新的数据。于是就出现了两个线程同时操作一个socket的局面。EPOLLONESHOT就可以解决这个问题,使得一个socket在连接的任意时间都只被一个线程处理。

对于注册了EPOLLONTSHOT事件的文件描述符,操作系统最多触发其上注册的一个可读可写或者异常事件,且只触发一次,除非我们使用epoll_ctl函数重置该文件描述符上注册的EPOLLONESHOT事件。

反向考虑,这种设计是对的,注册了EPOLLONESHOT事件的socket一旦被某个线程处理完毕,该线程就应该立即重置这个socket上的EPOLLONESHOT事件,以确保下一次可读的时候,其EPOLLIN事件可以被触发,进而让其他工作线程有机会继续处理这个socket。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值