zoukankan      html  css  js  c++  java
  • 比较一下Linux下的Epoll模型和select模型的区别

    一. select 模型(apache的常用)

    1. 最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制的,由 FD_SETSIZE 设置,默认值是 1024/2048 ,因此 Select 模型的最大并发数就被相应限制了。自己改改这个 FD_SETSIZE ?想法虽好,可是先看看下面吧 …

    2. 效率问题, select 每次调用都会线性扫描全部的 FD 集合,这样效率就会呈现线性下降,把 FD_SETSIZE 改大的后果就是,大家都慢慢来,什么?都超时了。

    3. 内核 / 用户空间 内存拷贝问题,如何让内核把 FD 消息通知给用户空间呢?在这个问题上 select 采取了内存拷贝方法,在FD非常多的时候,非常的耗费时间。

    总结为:1.连接数受限  2.查找配对速度慢 3.数据由内核拷贝到用户态消耗时间

    二. Epoll模型的提升(nginx的使用)

    再来看看 Epoll 的改进之处吧,其实把 select 的缺点反过来那就是 Epoll 的优点了。

    ①. Epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048, 一般来说这个数目和系统内存关系很大 ,具体数目可以 cat /proc/sys/fs/file-max 察看。

    ②. 效率提升, Epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境中, Epoll 的效率就会远远高于 select 和 poll 。

    ③. 内存共享, Epoll 在这点上使用了“共享内存 ”,这个内存拷贝也省略了。

    三. Epoll 为什么高效?

    Epoll 的高效和其数据结构的设计是密不可分的,这个下面就会提到。

    首先回忆一下 select 模型,当有 I/O 事件到来时, select 通知应用程序有事件到了快去处理,而应用程序必须轮询所有的 FD 集合,测试每个 FD 是否有事件发生,并处理事件;代码像下面这样:

     1 int res = select(maxfd+1, &readfds, NULL, NULL, 120);
     2 if (res > 0)
     3 {
     4     for (int i = 0; i < MAX_CONNECTION; i++)
     5     {
     6         if (FD_ISSET(allConnection[i], &readfds))
     7         {
     8             handleEvent(allConnection[i]);
     9         }
    10     }
    11 }
    12 // if(res == 0) handle timeout, res < 0 handle error

    Epoll 不仅会告诉应用程序有I/0 事件到来,还会告诉应用程序相关的信息,这些信息是应用程序填充的,因此根据这些信息应用程序就能直接定位到事件,而不必遍历整个FD 集合。类似的代码可能如下所示:

    1 int res = epoll_wait(epfd, events, 20, 120);
    2 for (int i = 0; i < res;i++)
    3 {
    4     handleEvent(events[n]);
    5 }

     Epoll 关键数据结构

     前面提到 Epoll 速度快和其数据结构密不可分,其关键数据结构就是:

     1 struct epoll_event {
     2     __uint32_t events;      // Epoll events
     3     epoll_data_t data;      // User data variable
     4 };
     5 typedef union epoll_data {
     6     void *ptr;
     7     int fd;
     8     __uint32_t u32;
     9     __uint64_t u64;
    10 } epoll_data_t;

    可见 epoll_data 是一个 union 结构体 , 借助于它应用程序可以保存很多类型的信息 :fd 、指针等等。有了它,应用程序就可以直接定位目标了。

    select模型的内核必须遍历所有监视的描述符,而应用程序也必须遍历所有描述符,检查哪些描述符已经准备好。当描述符成百上千时,会变得非常低效——这是

    select(poll)模型低效的根源所在。考虑这些情况,2.6以后的内核都引进了epoll模型。

  • 相关阅读:
    2020-04-07 python一行代码 http服务器文件共享
    2020-04-06 linux命令之awk
    2020-04-05 ubuntu安装docker并使用国内加速
    2020-04-04 ssh免密登录
    尚学堂 JAVA DAY11 概念总结
    尚学堂 JAVA Day3 概念总结
    尚学堂 JAVA Day1 概念总结
    Android Studio 首次安装报错 Java.lang.RuntimeException:java.lang.NullPointerException...错
    Android 迷之Version管理
    Android Develop 之 Ddevelop WorkFlow Basics
  • 原文地址:https://www.cnblogs.com/shangzekai/p/4626088.html
Copyright © 2011-2022 走看看