Linux中select poll和epoll的区别

2023-11-10

原文地址:http://www.cnblogs.com/bigwangdi/p/3182958.html


在Linux Socket服务器短编程时,为了处理大量客户的连接请求,需要使用非阻塞I/O和复用,select、poll和epoll是Linux API提供的I/O复用方式,自从Linux 2.6中加入了epoll之后,在高性能服务器领域得到广泛的应用,现在比较出名的nginx就是使用epoll来实现I/O复用支持高并发,目前在高并 发的场景下,nginx越来越收到欢迎。这里有个文章参考。Nginx成为全球Top1000网站最受欢迎的Web服务器。

据 w3techs 7月 3 日的统计数据表明,在全球 Top 1000 的网站中,有 34.9% 的网站在使用 Nginx,这使得 Nginx 超越了 Apache,成为了高流量网站最信任的 Web 服务器。下图是统计数据。

select:

下面是select的函数接口:

int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

 

select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过遍历fdset,来找到就绪的描述符。

select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点。select的一 个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低。

poll:

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

 

不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。

struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};

 

pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。

从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。

epoll:

epoll的接口如下:

int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *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 */
            };

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

 

主要是epoll_create,epoll_ctl和epoll_wait三个函数。epoll_create函数创建epoll文件描述符,参数size并不是限制了epoll所能监听的描述符最大个数,只是对内核初始分配内部数据结构的一个建议。返回是epoll描述符。-1表示创建失败。epoll_ctl 控制对指定描述符fd执行op操作,event是与fd关联的监听事件。op操作有三种:添加EPOLL_CTL_ADD,删除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。分别添加、删除和修改对fd的监听事件。epoll_wait 等待epfd上的io事件,最多返回maxevents个事件。

在 select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一 个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait() 时便得到通知。

epoll的优点主要是一下几个方面:

1. 监视的描述符数量不受限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。select的最大缺点就是进程打开的fd是有数量限制的。这对 于连接数量比较大的服务器来说根本不能满足。虽然也可以选择多进程的解决方案( Apache就是这样实现的),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也 不是一种完美的方案。

2. IO的效率不会随着监视fd的数量的增长而下降。epoll不同于select和poll轮询的方式,而是通过每个fd定义的回调函数来实现的。只有就绪的fd才会执行回调函数。

3.支持电平触发和边沿触发(只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发)两种方式,理论上边缘触发的性能要更高一些,但是代码实现相当复杂。

4.mmap加速内核与用户空间的信息传递。epoll是通过内核于用户空间mmap同一块内存,避免了无畏的内存拷贝。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux中select poll和epoll的区别 的相关文章

随机推荐

  • redis 获取 list 中的所有元素

    一种方法是用 lrange key 0 1 这种方法不会影响 redis list 中的数据 List
  • QT 网络编程之https

    HTTP 超文本传输协议 是一个基于请求与响应 无状态的 应用层的协议 常基于TCP IP协议传输数据 互联网上应用最为广泛的一种网络协议 所有的WWW文件都必须遵守这个标准 设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法 H
  • 【Python-3.5】matplotlib做简单折线图

    在matplotlib中使用plot 函数可以做出简单折线图 预期效果如下 代码如下 导入pyplot模块 import matplotlib pyplot as plt 输入横纵坐标数据 months 1 2 3 4 5 6 people
  • 分布式事务解决方案

    一 概述 分布式事务 分布式系统会把一个应用拆分为多个可独立部署的服务 此时要完成事务 就需要这些服务之间远程交互完成事务 简单的说跨JVM进程或者跨数据库实例产生分布式事务 典型的分布式事务场景 跨库事务 一个应用中某个功能需要操作多个库
  • Android基础-Service和IntentService知识点详细总结

    Service 对于广大的Android开发者来说算是耳熟能详了 作为Android的四大组件之一 在我们的开发中也起着重要的作用 在Android面试中 Service相关的问题也是面试官问得比较多的 当别人问你 Service 到底是什
  • 【torch.nn.init】初始化参数方法解读

    可参考 torch nn init 云 社区 腾讯云 一 torch nn init constant tensor val 1 作用 常数分布 用值val填充向量 2 参数 tensor an n dimensional torch Te
  • 青藤首提“业安融合”理念,正式发布先进云安全方案CNAPP

    4月18日 青藤以 云时代 安全变了 为主题的2023年云安全高峰论坛在北京成功举办 会上 青藤首次提出 业安融合 理念 正式发布先进云安全方案CNAPP 中国全面进入云和数字化时代 当前 全球已进入数字经济时代 我国高度重视数字经济发展
  • Postgresql on conflict do update 设置当前值,原始值,当前值与原始值相加值

    Postgresql插入时主键冲突会报错 可采取冲突不做任何处理或者进行更新 俩种方式避免报错 更新时可以保存新值 保存新值与旧值表达式 更新时可以保存原来的值 ON CONFLICT date city DO NOTHING 或者 ON
  • JVM —堆内存区域的认识

    一个JVM只有一个堆 堆的大小是可以调节的 堆中存放的内容 当类加载器读取完类文件后 会把类 方法 常量 变量等存放在堆中 保存的是我们所有引用对象的真实对象 也就是真实引用对象的数据等 堆内存中的三个区域 新生区 老年区 永久区 堆中要进
  • 【Typescript】ts中的静态属性和静态方法

    Typescript中的静态属性和静态方法 在ts中使用静态属性和方法 需要有static关键字 且在静态方法里只能用静态属性 举两个栗子 在es5中 function Person this run1 function 实例方法 实例化后
  • 特征缩放(归一化处理)

    在我们面对多维特征问题的时候 我们要保证这些特征都具有相近的尺度 这将帮助梯度下降算法更快地收敛 以房价问题为例 假设我们使用两个特征 房屋的尺寸和房间的数量 尺寸的值为 0 2000平方英尺 而房间数量的值则是0 5 以两个参数分别为横纵
  • 带有 OpenCV.js 的 ESP32-CAM Web 服务器:颜色识别和跟踪

    本教程介绍了使用 ESP32 摄像头网络服务器环境的 OpenCV js 和 OpenCV 工具 例如 我们将构建一个简单的 ESP32 摄像头网络服务器 其中包括对移动物体的颜色检测和跟踪 本教程绝不是对 OpenCV 可以提供给 ESP
  • 学乐高机器人还是学习少儿编程

    学乐高机器人还是学习少儿编程 对于很多的家长来说 孩子的学习一直都是他们非常关心和重视的一件事情 很多的家长在给孩子选择学习课程的时候 也是非常的耐心的 他们会给孩子选择一些能够有利于孩子成长的课程 就拿现在很多的家长想要孩子去学习机器人编
  • 生成树协议实验报告_“网络工程师培训”基础教程:OSPF协议及配置

    OSPF协议概述 OSPF 是 Open Shortest Path First 即 开放最短路由优先协议 的缩写 它是 IETF 组织开发的一个基于链路状态的自治系统内部路由协议 在IP 网络上 它通过收集和传递自治系统的链路状态来动态地
  • 牛客网Verilog刷题——VL54

    牛客网Verilog刷题 VL54 题目 答案 题目 实现一个深度为8 位宽为4bit的双端口RAM 数据全部初始化为0000 具有两组端口 分别用于读数据和写数据 读写操作可以同时进行 当读数据指示信号read en有效时 通过读地址信号
  • ffmpeg命令行map参数的使用

    介绍 理解 map参数的最好办法就是想像一下怎么去告诉ffmpeg你要从源文件中选择 拷贝哪个流到输出文件 输出文件的stream顺序取决于在命令行中 map的参数顺序 下面有一些例子 默认 默认操作 没有指定map参数 比如 ffmpeg
  • IR2104电机驱动

    目录 一 IR2104的引脚定义 二 IR2104的内部原理 三 半桥驱动原理分析 四 全桥驱动原理分析 五 电感电流回流路径的建立 六 自举电容容值的计算与自举二极管选型 七 mos管发热可能的问题 八 推荐阅读 一 IR2104的引脚定
  • R语言中如何进行PCA分析?利用ggplot和prcomp绘制基因表达量分析图

    学习笔记的主要内容是在R语言中利用ggplot2进行PCA分析和绘图 包括简单分析与操作流程 对比不同方式得到的结果差异 提供脚本代码供练习 PCA分析的原理 在处理基因差异表达数据时 有时候需要分析其中因素的影响最大 判断结果的关系 这个
  • InstructGPT:彻底改变人工智能驱动的语言模型

    目录 什么是InstructGPT 人工智能驱动的语言模型的演变 InstructGPT 模型与 GPT 3 相比如何 通过 OpenAI API 访问 InstructGPT 1 访问platform openai com并创建或登录您的
  • Linux中select poll和epoll的区别

    原文地址 http www cnblogs com bigwangdi p 3182958 html 在Linux Socket服务器短编程时 为了处理大量客户的连接请求 需要使用非阻塞I O和复用 select poll和epoll是Li