今天看公司代码时,发现代码里面使用的事清一色的代码使用epoll,

  所以就得说一说了;宏观看一看epoll 和select的实现:

select原理概述

调用select时,会发生以下事情:

  1. 从用户空间拷贝fd_set到内核空间;
  2. 注册回调函数__pollwait;
  3. 遍历所有fd,对全部指定设备做一次poll(这里的poll是一个文件操作,它有两个参数,一个是文件fd本身,一个是当设备尚未就绪时调用的回调函数__pollwait,这个函数把设备自己特有的等待队列传给内核,让内核把当前的进程挂载到其中);
  4. 当设备就绪时,设备就会唤醒在自己特有等待队列中的【所有】节点,于是当前进程就获取到了完成的信号。poll文件操作返回的是一组标准的掩码,其中的各个位指示当前的不同的就绪状态(全0为没有任何事件触发),根据mask可对fd_set赋值;
  5. 如果所有设备返回的掩码都没有显示任何的事件触发,就去掉回调函数的函数指针,进入有限时的睡眠状态,再恢复和不断做poll,再作有限时的睡眠,直到其中一个设备有事件触发为止。
  6. 只要有事件触发,系统调用返回,将fd_set从内核空间拷贝到用户空间,回到用户态,用户就可以对相关的fd作进一步的读或者写操作了。

epoll原理概述

调用epoll_create时,做了以下事情:

  1. 内核帮我们在epoll文件系统里建了个file结点;
  2. 在内核cache里建了个红黑树用于存储以后epoll_ctl传来的socket;
  3. 建立一个list链表,用于存储准备就绪的事件。

调用epoll_ctl时,做了以下事情:

  1. 把socket放到epoll文件系统里file对象对应的红黑树上;
  2. 给内核中断处理程序注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到准备就绪list链表里。

调用epoll_wait时,做了以下事情:

观察list链表里有没有数据。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。而且,通常情况下即使我们要监控百万计的句柄,大多一次也只返回很少量的准备就绪句柄而已,所以,epoll_wait仅需要从内核态copy少量的句柄到用户态而已。

select缺点:

  1. 最大并发数限制:使用32个整数的32位,即32*32=1024来标识fd,虽然可修改,但是有以下第二点的瓶颈;
  2. 效率低:每次都会线性扫描整个fd_set,集合越大速度越慢;
  3. 内核/用户空间内存拷贝问题。

epoll的提升:

  1. 本身没有最大并发连接的限制,仅受系统中进程能打开的最大文件数目限制;
  2. 效率提升:只有活跃的socket才会主动的去调用callback函数;
  3. 省去不必要的内存拷贝:epoll通过内核与用户空间mmap同一块内存实现。

  假设现在有1024个fd ; select 和epoll 都同时维护他, 假设这些fd 都是活跃的, 这种情况下,select一次扫描 可以扫描1024个fd,空闲的fd很少,

但是epoll 就有可能不一样了, epoll 是先注册等待回调, 有可能出现1024次回调;

  这样的情况下, 要是说epoll 效率比select 高-----这就不好说了!!!!!!!!

  如果select 和epoll 同时维护1024个fd ,但是每次只有一个fd有事件,这种情况下 select 每次都会扫描所有的fd,  对比于epoll 每次只有一个fd 回调。 select 做了很多无用功, 此时应该epoll的效率高吧!!

  或者在短连接多的时候, 一个连接使用epoll 会触发epoll_ctrl_add/del 两次系统调用,但是select 只有一次扫描 ,此时 也许select 效率性能更高。

高并发,且任一时间只有少数socket是活跃的。如果在并发量低,socket都比较活跃的情况下,select就不见得比epoll慢了

  所以 I/O复用模型 要根据业务需求来选择,技术只有合适的技术-----------------------

终于找到这张神图了

为什么人们总是认为epoll 效率比select高!!!!!!的更多相关文章

  1. epoll对poll(select)的改进

    select的几大缺点:   每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大: 每次调用select,内核需要遍历传递进来的所有fd(判断检测文件是否可用).有 ...

  2. Linux中epoll+线程池实现高并发

    服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指“I/O线程”,即负责I/O操作,协调分配任务的“管理线程”,而实际的请求和任务通常交由所谓“工作者线程”处理.通常多线程模型下,每个线程 ...

  3. centos LB负载均衡集群 三种模式区别 LVS/NAT 配置 LVS/DR 配置 LVS/DR + keepalived配置 nginx ip_hash 实现长连接 LVS是四层LB 注意down掉网卡的方法 nginx效率没有LVS高 ipvsadm命令集 测试LVS方法 第三十三节课

    centos   LB负载均衡集群 三种模式区别 LVS/NAT 配置  LVS/DR 配置  LVS/DR + keepalived配置  nginx ip_hash 实现长连接  LVS是四层LB ...

  4. 《【面试突击】— Redis篇》-- Redis的线程模型了解吗?为啥单线程效率还这么高?

    能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis的线程模型了解吗?为啥单线程效率还这 ...

  5. 老徐和阿珍的故事:ArrayList和LinkedList的效率到底哪个高?

    人物背景: 老徐,男,本名徐福贵,从事Java相关研发工作多年,职场老油条,摸鱼小能手,虽然岁数不大但长的比较着急,人称老徐.据说之前炒某币败光了所有家产,甚至现在还有欠债. 阿珍,女,本名陈家珍,刚 ...

  6. 比较一下Linux下的Epoll模型和select模型的区别

    一. select 模型(apache的常用) 1. 最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制的,由 FD_SETSIZE 设置,默认值是 1024/2048 ,因此 Sel ...

  7. Redis不是一直号称单线程效率也很高吗,为什么又采用多线程了?

    Redis是目前广为人知的一个内存数据库,在各个场景中都有着非常丰富的应用,前段时间Redis推出了6.0的版本,在新版本中采用了多线程模型. 因为我们公司使用的内存数据库是自研的,按理说我对Redi ...

  8. redis为何单线程 效率还这么高 为何使用跳表不使用B+树做索引(阿里)

    如果想了解 redis 与Memcache的区别参考:Redis和Memcache的区别总结 阿里的面试官问问我为何redis 使用跳表做索引,却不是用B+树做索引 因为B+树的原理是 叶子节点存储数 ...

  9. 冷知识:达夫设备(Duff's Device)效率真的很高吗?

    ID:技术让梦想更伟大 作者:李肖遥 wechat链接:https://mp.weixin.qq.com/s/b1jQDH22hk9lhdC9nDqI6w 相信大家写业务逻辑的时候,都是面向if.el ...

随机推荐

  1. Python数据类型--元组(tuple)

    元组与列表非常相似,最大区别在于: (1)元组是不可修改的,定义之后就"固定"了. (2)元组在形式上是用()这样的圆括号括起来 (3)元组不能插入或删除元素 注:元素可修改与不可 ...

  2. 2017年 实验三 C2C模拟实验

    [实验目的] 掌握网上购物的基本流程和C2C平台的运营 [实验条件] ⑴.个人计算机一台 ⑵.计算机通过局域网形式接入互联网. (3).奥派电子商务应用软件 [知识准备] 本实验需要的理论知识:C2C ...

  3. 多测师讲解unittest介绍及自动化测试实现流程_高级讲师肖sir

    unittest框架介绍 unittest框架是python中一个标准的库中的一个模块,该模块包括许多的类如 test case类.test suit类.texttest runner类.textte ...

  4. MeteoInfoLab脚本示例:加载图片和透明图层

    MeteoInfoLab的georead函数提供了读取shape文件.image文件(JPG.PNG等,需要有相应的地理定位文件)文件生成图层的功能(事实上shaperead也是同样的功能,不过函数名 ...

  5. MeteoInfoLab脚本示例:MERRA HDF数据

    MERRA是NOAA的一种再分析资料,HDF数据遵循COARDS协议,读取比较简单.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = 'MERRA3 ...

  6. day40 Pyhton 并发编程03

    一.内容回顾 进程是计算机中最小的资源分配单位 进程与进程之间数据隔离,执行过程异步 为什么会出现进程的概念? 为了合理利用cpu,提高用户体验 多个进程是可以同时利用多个cpu的,可以实现并行的效果 ...

  7. linux(centos8):kubeadm单机安装kubernetes(kubernetes 1.18.3)

    一,kubernetes安装的准备工作: 1,准备工作的各步骤请参见: https://www.cnblogs.com/architectforest/p/13141743.html   2,  ma ...

  8. Linux文件系统和管理-2文件操作命令(下)

    移动和重命名文件 mv 命令可以实现文件或目录的移动和改名 剪切的效果 同一分区移动数据,速度很快:数据位置没有变化 不同分区移动数据,速度相对慢:数据位置发生了变化 格式 和cp基本一样 mv [O ...

  9. 链接WPA2-企业WIFI时出现无法链接到该网络,可以链接个人WIFI时的问题和解决方案

    因在一个问题上掉两次坑所以还是决定记录下来,方便以后查阅. 第一次因为要部署.net 应用程序要求使用TLS1.2,所以修改了操作系统的默认启用的安全协议类型,导致好多应用程序出问题. 第二次因为vs ...

  10. python模块导入(包)

    模块 关注公众号"轻松学编程"了解更多. 1.1. 模块的概述 ​ 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里的代码就会越来越长,越来越不容易维护. 为了编写可维 ...