加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

UNIX情形高级编程:select和epoll的区别

发布时间:2016-10-31 03:13:30 所属栏目:Unix 来源:站长网
导读:副标题#e# select 和epoll都用于监听套接口描述字上是否有事件发生,实现I/O复用 select (轮询) #include sys/select.h #include sys/time.h int select (int maxfdpl, fd_set* readset, fd_set* writeset, fd_set* exceptset, const struct timeval* tim

等待函数

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

等待事件的产生,参数events用来从内核得到事件集合。maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间(毫秒,0会立即返回,-1永久阻塞)。该函数返回需要处理的事件数目,如返回0表示已超时。
注意:某fd上发生事件后,其事件类型会被清空,所以如果下一个循环还要关注这个socket fd的话,则需要用epoll_ctl(epfd,EPOLL_CTL_MOD,listenfd,&ev)来重新设置socket fd的事件类型。这时不用EPOLL_CTL_ADD,因为socket fd并未清空,只是事件类型清空。这一步非常重要。

实例

struct epoll_event ev, *events;  
      
for(;;) {  
    nfds = epoll_wait(kdpfd, events, maxevents, -1);  
      
    for(n = 0; n < nfds; ++n) {  
       if(events[n].data.fd == listener) {  
          client = accept(listener, (struct sockaddr *) &local,  
                          &addrlen);  
          if(client < 0){  
             perror("accept");  
             continue;  
          }  
          setnonblocking(client);  
          ev.events = EPOLLIN | EPOLLET;  
          ev.data.fd = client;  
          if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {  
              fprintf(stderr, "epoll set insertion error: fd=%dn",  
                       client);  
               return -1;  
          }  
       } else {  
          do_use_fd(events[n].data.fd);  
       }  
    }

对比:

select - 如果同时建立很多连接,但只有少数事件发生,这种轮询会造成效率很低;频繁从内核拷贝、复制描述字;监听描述字受限于内核的FD_SETSIZE;

epoll - 这种回调触发式操作会保证效率;不需要频繁的拷贝;监听描述字没有限止,只与系统资源有关;epoll返回时已经明确的知道哪个sokcet fd发生了事件,,不用再一个个比对。

查看本栏目更多精彩内容:http://www.bianceng.cn/OS/unix/

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读