精华内容
下载资源
问答
  • epoll和select的区别

    千次阅读 2016-10-13 10:17:08
    要了解epoll和select的区别,首先来理解一下epoll和select各自的功能和属性。poll和epoll和select都是多路复用下的一种机制,多路复用I/O就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪,就通知...

    要了解epoll和select的区别,首先来理解一下epoll和select各自的功能和属性。poll和epoll和select都是多路复用下的一种机制,多路复用I/O就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪,就通知程序该文件描述符可以进行读写操作。

    select():用于确定一个或多个套接口的状态。
    select的几大缺点(不可忽视):
    1、每次调用select()的时候,都必须要将fd从用户态转换成内核态,这个开销在fd很多的时候非常大。
    2、调用select()的时候,在操作系统内核API都会遍历整个fd集,这会大大影响系统效率。
    3、select()可打开的文件描述符的上限太少了,默认是1024个。

    epoll ():是Linux下为处理大批量文件描述符而作了改进的poll,是Linux下多路复用I/O接口poll/select的增强版本,能够显著的提高在大量并发连接中只有少数连接活跃的系统CPU利用率。它在获取事件的时候,不会将整个文件描述符集全部遍历,只需要遍历那些被系统API异步唤醒后放入Ready队列的文件描述符。有两种触发的方式,分别是边沿触发和水平触发方式。
    因为epoll是poll和select的改进版,所以对于select的缺点也作了相应的处理。epoll里面有三个函数,分别是:epoll_create(用于创建一个epoll句柄), epoll_wait(用于等待一个事件), epoll_ctl(用于注册要监听的事件类型).
    1、对于第一个缺点,epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD)重点内容,会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
    2、对于第二个缺点,epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)。
    3、对于第三个缺点,epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
    区别:1、select在每次被调用的时候,都会讲所有fd从用户态转换成内核态,而epoll只是在事件注册的时候只拷贝一次fd而已。提高了效率。
    2、对于select来说,在每次醒着的时候,都需要将整个fd遍历一遍,而对于epoll来说,只需要在current的时候挂一遍fd,然后设置一个回调函数,当设备准备完成时,就调用一个回调函数将对应的文件描述符返还给进程,所以在时间上要大大的提高于select。
    3、select的文件描述符的上限默认是1024,但是epoll没有这个限制,可以远大于1024,因为它只和系统的内存大小有关,而不受限于一个定值。

    展开全文
  • epoll select 的区别

    千次阅读 2015-08-25 19:43:10
    关于epoll和select之间的区别

       面试linux的时候,很多面试官都会问的一个问题是epoll和select的区别,而我总是答的不够完整,今天总结一下epoll和select的区别。

       首先select是posix支持的,而epoll是linux特定的系统调用,因此,epoll的可移植性就没有select好,但是考虑到epoll和select一般用作服务器的比较多,而服务器中大多又是linux,所以这个可移植性的影响应该不会很大。

       其次,select可以监听的文件描述符有限,最大值为1024,而epoll可以监听的文件描述符则是系统对整个进程限制的最大文件描述符。

       接下来就要谈epoll和select的性能 比较了,这个一般情况下应该是epoll表现好一些,否则linux也不会去特定实现epoll函数了,那么epoll为什么比select更高效呢?原因有很多,第一点,epoll通过每次有就绪事件时都将其插入到一个就绪队列中,使得epoll_wait的返回结果中只存储了已经就绪的事件,而select则返回了所有被监听的事件,事件是否就绪需要应用程序去检测,那么如果已被监听但未就绪的事件较多的话,对性能的影响就比较大了。第二点,每一次调用select获得就绪事件时都要将需要监听的事件重复传递给操作系统内核,而epoll对监听文件描述符的处理则和获得就绪事件的调用分开,这样获得就绪事件的调用epoll_wait就不需要重新传递需要监听的事件列表,这种重复的传递需要监听的事件也是性能低下的原因之一。除此之外,epoll的实现中使用了mmap调用使得内核空间和用户空间共享内存,从而避免了过多的内核和用户空间的切换引起的开销。

       然后就是epoll提供了两种工作模式,一种是水平触发模式,这种模式和select的触发方式是一样的,即只要文件描述符的缓冲区中有数据,就永远通知用户这个描述符是可读的,这种模式对block和noblock的描述符都支持,编程的难度也比较小 ; 而另一种更高效且只有epoll提供的模式是边缘触发模式,只支持nonblock的文件描述符,他只有在文件描述符有新的监听事件发生的时候(例如有新的数据包到达)才会通知应用程序,在没有新的监听时间发生时,即使缓冲区有数据(即上一次没有读完,或者甚至没有读),epoll也不会继续通知应用程序,使用这种模式一般要求应用程序收到文件描述符读就绪通知时,要一直读数据直到收到EWOULDBLOCK/EAGAIN错误,使用边缘触发就必须即将缓冲区中的内容读完,否则有可能引起死等,尤其是当一个listen_fd需要监听到达连接的时候,如果多个连接同时到达,如果每次只是调用accept一次,就会导致多个连接在内核缓冲区中滞留,处理的办法是用while循环抱住accept,直到其出现EAGAIN。这种模式虽然容易出错,但是性能要比前面的模式更高效,因为只需要监听是否有事件发生,发生了就直接将描述符加入就绪队列即可。


    展开全文
  • epoll 和select的区别

    2020-09-22 21:26:19
    epoll是基于事件驱动,哪个流发生了怎么样I/O事件通知我们,事件复杂度是o(1),没有最大并发连接限制,epoll 对于1G内存可以支持10万个,可以通过/proc/sys/fs/file-max可以查看到,对于内存拷贝:使用mm....

    相同点:都是多路复用

     

    不同点:

    select是轮询所有的流,时间辅助度是0(n),处理的流越多,无差别轮询时间就越长;

    单个进程可监控的fd数量是有限的,32位机默认是1024;64位的是2048,内核需要将消息传递到用户空间,都需要内核拷贝动作

     

    epoll是基于事件驱动的,哪个流发生了怎么样的I/O事件通知我们,事件复杂度是o(1),没有最大并发连接的限制,epoll 对于1G的内存可以支持10万个,可以通过/proc/sys/fs/file-max可以查看到,对于内存的拷贝:使用mmap()文件映射加速和内核空间的消息传递,减少内存的复制开销。  ET  (边缘触发)和  LT   (水平触发) , LT:默认的发式,只要fd还有数据,每次epoll_wait都会返回它的事件,无论fd是否是可读还是可写。ET:它只会提示一次,知道下次有数据,所以一定要每次把数据读光

     

     

    如果连接数较少并且连接十分活跃的情况下,select比epoll要好,毕竟epoll通知机制要很多回调函数

     

    https://www.cnblogs.com/aspirant/p/9166944.html

    展开全文
  • 问题:关于 epoll select 的区别,哪些说法是正确的?(多选) A. epoll select 都是 I/O 多路复用的技术,都可以实现同时监听多个 I/O 事件的状态。 B. epoll 相比 select 效率更高,主要是基于其操作系统...

    问题:关于 epoll 和 select 的区别,哪些说法是正确的?(多选)

    A. epoll 和 select 都是 I/O 多路复用的技术,都可以实现同时监听多个 I/O 事件的状态。

    B. epoll 相比 select 效率更高,主要是基于其操作系统支持的I/O事件通知机制,而 select 是基于轮询机制。

    C. epoll 支持水平触发和边沿触发两种模式。

    D. select 能并行支持 I/O 比较小,且无法修改。

    出题人:阿里巴巴出题专家:寈峰/阿里技术专家

    参考答案:A,B,C

    【延伸】那在高并发的访问下,epoll使用那一种触发方式要高效些?当使用边缘触发的时候要注意些什么东西,下面将详细讲解epoll

    • epoll是什么

      • epoll 是Linux下多路复用IO接口 select/poll 的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率,因为它会复用文件描述符集用来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。

      • epoll除了提供 select/poll 那种IO事件的电平触发 (Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少 epoll_wait/epoll_pwait 的调用,提高应用程序效率。

    epoll函数

    • 说明:epoll对IO接口进行多路复用,提高CPU的利用率

    • 头文件:#include <sys/epoll.h>

    • 函数1:int epoll_create1(int flags);(向内核注册并打开一个 epoll 描述符)

      • 这个函数是在linux 2.6.27中加入的,它和 epoll_create 差不多,不同的是 epoll_create1 函数的参数是 flag,当 flag 是 0 时,表示和 epoll_create 函数完全一样,不需要 size 的提示了。

        • 当 flag = EPOLL_CLOEXEC,创建的epfd会设置FD_CLOEXEC(一般使用这种)

          • FD_CLOEXEC:它是 fd 的一个标识说明,用来设置文件 close-on-exec 状态的。当 close-on-exec 状态为 0 时,调用 exec 时,fd 不会被关闭;状态非零时则会被关闭,这样做可以防止 fd 泄露给执行 exec 后的进程。
        • 当 flag = EPOLL_NONBLOCK,创建的 epfd 会设置为非阻塞

      • int epoll_create(int size);

        • 创建一个 epoll 的句柄,size用来告诉内核这个监听的数目最大值。

        • 当创建好 epoll 句柄后,它就是会占用一个 fd 值,所以在使用完 epoll 后,必须调用 close() 关闭,否则可能导致 fd 被耗尽。

        • 注意:是数量的最大值,不是 fd 的最大值(通知内核需要监听 size 个fd)。

        • 自从Linux2.6.8版本以后,size值其实是没什么用的,不过要大于0,因为内核可以动态的分配大小,所以不需要 size 这个提示了。

      • 为什么使用 epoll_create1 函数而不用以前的 epoll_create 函数:

        • epoll_create 的参数 size 是老版本的实现,使用的是 hash 表, size 应该是用来算 bucket 数目,后面因为使用红黑树,这个参数不再使用, 可以忽略。
      • 返回值:成功返回一个非负的文件描述符,出错返回-1,并设置errno:

        • EINVAL : 无效的标志
        • EMFILE : 用户打开的文件超过了限制
        • ENFILE : 系统打开的文件超过了限制
        • ENOMEM : 没有足够的内存完成当前操作
    • 函数2:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);(epoll 的事件注册函数)

      • epfd参数:epoll_create1 函数返回的的 epoll 描述符

      • op参数:操作值(想要注册的动作)

        • EPOLL_CTL_ADD: 注册目标fd到epfd中,同时关联内部event到fd上
        • EPOLL_CTL_MOD: 修改已经注册到fd的监听事件
        • EPOLL_CTL_DEL: 从epfd中删除/移除已注册的fd,event可以被忽略,也可以为NULL
      • fd参数:需要监听的套接字描述符

      • event参数:设定监听事件的结构体

        • typedef union epoll_data {
              void        *ptr;
              int          fd;
              __uint32_t   u32;
              __uint64_t   u64;
          } epoll_data_t;
          
          struct epoll_event {
              __uint32_t   events; /* Epoll events */
              epoll_data_t data;   /* User data variable */
          };

          data是一个联合体,能够存储fd或其它数据,我们需要根据自己的需求定制。events表示监控的事件的集合,是一个状态值,通过状态位来表示,可以设置如下事件:

          • EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
          • EPOLLOUT:表示对应的文件描述符可以写;
          • EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
          • EPOLLERR:表示对应的文件描述符发生错误;
          • EPOLLHUP:表示对应的文件描述符被挂断;(并不代表对端结束了连接,通常情况下 EPOLLHUP 表示的是本端挂断)
          • EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
          • EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,就会把这个fd从epoll的队列中删除。如果还需要继续监听这个socket的话,需要再次把这个fd加入到EPOLL队列里
      • 返回值:成功返回0,失败返回-1,并设置errno:

        • EBADF : epfd 或者 fd 不是一个有效的文件描述符
        • EEXIST : op 为 EPOLL_CTL_ADD,但 fd 已经被监控
        • EINVAL : epfd 是无效的 epoll 文件描述符
        • ENOENT : op 为 EPOLL_CTL_MOD 或者 EPOLL_CTL_DEL,并且 fd 未被监控
        • ENOMEM : 没有足够的内存完成当前操作
        • ENOSPC : epoll 实例超过了 /proc/sys/fs/epoll/max_user_watches 中限制的监听数量
    • 函数3:int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask);

      • epfd参数:epoll 的描述符( epoll_create1 函数的返回值)

      • events参数:events 指针携带有 epoll_data_t 数据

      • maxevents参数:告诉内核 events 有多大,该值必须大于0,但是这个 maxevents 的值不能大于创建 epoll_create() 时的 size

      • timeout参数(毫秒):表示超时时间。0 表示不等待立即返回,-1 代表永久阻塞,大于 0 表示等待的最大时间

      • epoll_pwait(since linux 2.6.19)允许一个应用程序安全的等待,直到 fd 设备准备就绪,或者捕获到一个信号量。其中 sigmask 表示要捕获的信号量。

      • 返回值:成功返回准备好事件要求的描述符的个数,返回0代表在超时时间内没有准备好的描述符;失败返回 -1 并设置 errno:

        • EBADF:epfd 不是一个有效的描述符
        • EFAULT:events 指向的内存区域没有写的权限
        • EINTR:在事件发生任何请求或超时过期之前,调用被信号处理程序中断
        • EINVAL:epfd 不是一个 epoll 描述符,或者 maxevents 参数小于或等于 0
    • 示例:

      这里使用伪代码,具体实现的代码请移步

      epfd = epoll_create1(EPOLL_CLOEXEC);
      event.events = EPOLLET | EPOLLIN;
      event.data.fd = serverfd;
      epoll_ctl(epfd, EPOLL_CTL_ADD, serverfd, &event);
      // 主循环
      while(true) {
          // 这里的timeout很重要,实际使用中灵活调整
          count = epoll_wait(epfd, &events, MAXEVENTS, timeout);
          for(i = 0; i < count; ++i) {
              if(events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
                  // 处理错误
              if(events[i].data.fd == serverfd)
                  // 为接入的连接注册事件
              else if(events[i].events & EPOLLIN)
                  // 处理可读的缓冲区
                  read(events[i].data.fd, buf, len);
                  event.events = EPOLLET | EPOLLOUT;
                  event.data.fd = events[i].data.fd;
                  epoll_ctl(epfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
              else
                  // 处理可写的缓冲区
                  write(events[i].data.fd, buf, len);
                  // 后续可以关闭fd或者MOD至EPOLLOUT
          }
      }

    说明

    • 为什么用epoll

      • 支持监听大数目的socket描述符

        • 一个进程内,select能打开的fd是有限制的,由宏FD_SETSIZE 设置,默认值是 1024.在某些时候,这个数值是远远不够用的。解决办法有两种,一是修改宏然后重新编译内核,但与此同时会引起网络效率的下降;二是使用多进程来解决,但是创建多个进程是有代价的,而且进程间数据同步没有多线程间方便。

        • epoll没有这个限制,它所支持的最大 fd 上限远远大于1024,在1GB内存的机器上是10万左右(具体数目可以cat/proc/sys/fs/file-max查看)

          //我的是centos6.9,内存2GB
          [roux@Vkey mnt]$ cat /proc/sys/fs/file-max 
          187510
          [roux@Vkey mnt]$
      1. 效率的提高

        • select 函数每次都当监听的套接组有事件产生时就会返回,但却不能将有事件产生的套接字筛选出来,而是改变其在套接组的标志量,所以每次监听到事件,都需要将套接组整个遍历一遍。时间复杂度是O(n)。当fd数目增加时,效率会线性下降。

        • epoll 函数每次会将监听套结字中产生事件的套接字加到一列表中,然后我们可以直接对此列表进行操作,而没有产生事件的套接字会被过滤掉,极大的提高了IO效率。这一点尤其在套接字监听数量巨大而活跃数量很少的时候很明显。

      2. 内存处理

        • 不管是哪种I/O机制,都无法避免fd在操作过程中拷贝的问题,而 epoll 使用了 mmap (是指文件/对象的内存映射,被映射到多个内存页上),所以同一块内存(共享内存)就可以避免这个问题(详细看前面的零拷贝技术及 mmap)。
    • epoll的工作方式

      • epoll有两种触发模式,LT(Level-Triggered,水平触发),ET(Edge–Triggered边缘触发)。其中LT编程模型和poll是一样的。

      • LT(level triggered) 是默认/缺省的工作方式,同时支持 block 和 no_block socket。这种工作方式下,内核会通知你一个 fd 是否就绪,然后才可以对这个就绪的 fd 进行I/O操作。就算你没有任何操作,系统还是会继续提示 fd 已经就绪,不过这种工作方式出错会比较小,传统的 select/poll 就是这种工作方式的代表。(水平触发,只要有数据可以读,不管怎样都会通知)

      • ET(edge-triggered) 是高速工作方式 仅支持 no_block socket(非阻塞),这种工作方式下,当 fd 从未就绪变为就绪时,内核会通知 fd 已经就绪,并且内核认为你知道该 fd 已经就绪,不会再次通知了,除非因为某些操作导致fd就绪状态发生变化。如果一直不对这个 fd 进行I/O操作,导致 fd 变为未就绪时,内核同样不会发送更多的通知,因为 only once。所以这种方式下,出错率比较高,需要增加一些检测程序。(边缘触发,只有状态发生变化时才会通知,可以理解为电平变化)

      • 举例:

        • LT 水平触发

          儿子:“妈妈,我收到了5000元压岁钱。”
          妈妈:“恩,省着点花!”
          儿子:“妈妈,我今天买了个ipad,花了3000元。”
          妈妈:“噢,这东西真贵。”
          儿子:“妈妈,我今天买好多吃的,还剩1000元。”
          妈妈:“用完了这些钱,我可不会再给你了。”
          儿子:“妈妈,那1000元我没花,零花钱够用了。”
          妈妈:“恩,这才是明智的做法!”
          儿子:“妈妈,那1000元我没花,我要攒起来。”
          妈妈:“恩,加油!”

          • 是不是没完没了?只要儿子手中还有钱,他就会一直汇报,这就是LT模式。有钱就是1,没钱就是0,那么只要儿子还有钱,这种事件就是1->1类型事件,自然是LT。
        • ET 边缘触发

          儿子:“妈妈,我收到了5000元压岁钱。”
          妈妈:“恩,省着点花!”
          儿子:“……”
          妈妈:“你倒是说话啊?压岁钱呢?!”

          • 这个就是ET模式,简洁得有点过头,但很高效!虽然妈妈可能并不这么认为。。。儿子从没钱到有钱,是一个0->1的过程,因此为ET。儿子和妈妈说过自己拿到了压岁钱就完事了,至于怎么花钱,还剩多少钱,一概不说。
      • LT 模式和 ET 模式的区别是 ET 模式是高电平到低电平切换的时候或者低电平切换高电平才会触发。

        • EPOLLIN事件:

          • 内核的输入缓冲区 为空 低电平
          • 内核的输入缓冲区 不为空 高电平(一直触发EPOLLIN)
        • EPOLLOUT事件:

          • 内核发送缓冲区不满 高电平(一直触发EPOLLOUT)
          • 内核发送缓冲区满 低电平
      • 关于 LT 及 ET 的详细知识请点击此处

    • 什么时候关注EPOLLOUT事件呢?(如果在得到一个套接字马上关注,就会出现busy loop的状态)

      • LT 模式:在write的时候关注EPOLLOUT事件,如果数据没有写完,我们就需要把未发送完的数据添加到应用层缓冲区,然后关注这个连接套接字的EPOLLOUT事件,等到EPOLLOUT事件到来,取出应用层缓冲区的数据发送,如果应用层缓冲区数据发送完成,取消关注EPOLLOUT事件。

      • ET 模式:ET表示边缘触发,是电平从低到高或者从高到低才会触发。我们一开始就可以关注EPOLLIN事件和EPOLLOUT事件,不会出现busy loop。所以当接收缓冲区处于高电平状态时,一定要一次性把数据全部读完。因为如果一次没有读完,接收缓冲区仍然处于高电平状态,下次不会在触发EPOLLIN事件。同理,发送缓冲区的处理类似。

    注意

    • epoll 和 select/poll 本质上是一样的,性能上提升较大,都属于I/O多路复用模型(I/O Multiplexing Model),和阻塞,非阻塞两大I/O模型是并列的。只是对于事件处理函数角度而言,看起来是异步的(实际上是同步的回调而已)。和 epoll 组合使用大多数是非堵塞I/O方式,这时候就是同步非堵塞,也可以有堵塞I/O的情况。比如多线程server可以在 accept 上采用堵塞I/O,accept后的 socket 用 epoll 管理非堵塞的读写事件。

    • 使用 epoll 一定要加 定时器,否则后患无穷

    • 联合体 data 中的那个 ptr 是很有用的,只不过这就意味着你将该对象的生命周期交给了 epoll,不排除会有潜在bug的影响,需要辅以timeout

    • 多线程环境下使用epoll,多考虑 EPOLLONESHOT

    • EPOLLLT 也是一个不错的选择,除非你的框架能够确保每次事件触发后,都读/写至 EAGAIN

    • 使用前请仔细阅读 man 7 epoll

    总结

    • epoll 实现机制(简单介绍)

      • epoll在被内核初始化时(操作系统启动),同时会开辟出epoll自己的内核高速cache区,用于安置每一个我们想监控的socket。这些socket会以红黑树的形式保存在内核cache里,以支持快速的查找、插入、删除。

      • 这个内核高速cache区,就是建立连续的物理内存页,然后在之上建立 slab 层。简单的说,就是物理上分配好你想要的size的内存对象,每次使用时都是使用空闲的已分配好的对象。

      • epoll的高效就在于,当我们调用 epoll_ ctl 往里塞入百万个句柄时,epoll_ wait 仍然可以飞快的返回,并有效的将发生事件的句柄给我们用户。

        • 这是由于我们在调用 epoll_ create 时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个红黑树用于存储以后 epoll_ ctl 传来的socket外,还会再建立一个list链表,用于存储准备就绪的事件.
      • 当 epoll_ wait 调用时,仅仅观察这个list链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait 非常高效。 而且,通常情况下即使我们要监控百万计的句柄,大多一次也只返回很少量的准备就绪句柄而已,所以,epoll_wait 仅需要从内核态copy少量的句柄到用户态而已。

      • 那么,这个准备就绪list链表是怎么维护的呢?

        • 当我们执行 epoll_ctl 时,除了把socket放到epoll文件系统里file对象对应的红黑树上之外,还会给内核中断处理程序注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到准备就绪list链表里。

        • 所以,当一个socket上有数据到了,内核在把网卡上的数据copy到内核中后就来把socket插入到准备就绪链表里了。如此,一颗红黑树,一张准备就绪句柄链表,少量的内核cache,就帮我们解决了大并发下的socket处理问题。

      • 执行 epoll_ create 时,创建了红黑树和就绪链表,执行 epoll_ ctl 时,如果增加socket句柄,则检查在红黑树中是否存在,存在立即返回,不存在则添加到树干上,然后向内核注册回调函数,用于当中断事件来临时向准备就绪链表中插入数据。执行 epoll_wait 时立刻返回准备就绪链表里的数据即可。

    • 三种IO复用函数的分析

    参考

    展开全文
  • 问题1:关于 epoll select 的区别,哪些说法是正确的?(多选) A. epoll select 都是 I/O 多路复用的技术,都可以实现同时监听多个 I/O 事件的状态。 B. epoll 相比 select 效率更高,主要是基于其操作系统...
  • 这里主要讲epoll和另外两个的区别,另外再把epoll的一个简单运用实例说说。 (一)epoll 有select,poll的主要区别: 一、相比于select与poll, epoll最大的好处在于它不会随着监听fd数目的增长而降低效率; 二、...
  • 关于epoll和select的区别,哪些说法是正确的? 正确答案: A B C epoll和select都是I/O多路复用的技术,都可以实现同时监听多个I/O事件的状态 epoll相比select效率更高,主要是基于其操作系统支持...
  • epoll早期用过hashmap(效率高)但是因为占用空间大所以改成了红黑树。
  • 先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一、问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符...
  • 为帮助开发者们提升面试技能、有机会入职阿里,云栖社区特别制作了这个专辑——阿里巴巴资深技术专家们结合多年工作、面试经验总结提炼而成面试真题这一次将陆续放出(面试题官方参考答案将在专辑结束后统一汇总...
  • 为什么80%码农都做不了架构师?>>> ...
  • 摘要: 阿里巴巴资深技术专家们结合多年工作、面试经验总结提炼而成笔试真题这一次将陆续放出(面试题答案将在专辑分享结束后统一汇总分享)。并通过这些笔试真题开放阿里巴巴工作机会,让更多开发者加入到...
  • 最近在用epoll,网速资料很多,大家都说epoll和select的区别比较大,而且select要不停遍历所有的fd,效率要低,而且fd有限制。 但是我认为二者最大的区别在于 先看代码 while (1) { nfds = epoll_wait(epfd, ...
  • epoll和select区别

    2015-04-16 21:55:00
    epoll和select区别 先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一、问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长...
  • linux中 epoll poll 和select的区别

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,105
精华内容 442
关键字:

epoll和select的区别