操作系统在处理io的时候,主要有两个阶段:

  • 等待数据传到io设备
  • io设备将数据复制到user space

我们一般将上述过程简化理解为:

  • 等到数据传到kernel内核space
  • kernel内核区域将数据复制到user space(理解为进程或者线程的缓冲区)

  select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。


select

  单个进程就可以同时处理多个网络连接的io请求(同时阻塞多个io操作)。基本原理就是程序呼叫select,然后整个程序就阻塞状态,这时候,kernel内核就会轮询检查所有select负责的文件描述符fd,当找到其中那个的数据准备好了文件描述符,会返回给select,select通知系统调用,将数据从kernel内核复制到进程缓冲区(用户空间)。

下图为select同时从多个客户端接受数据的过程

虽然服务器进程会被select阻塞,但是select会利用内核不断轮询监听其他客户端的io操作是否完成



Poll介绍

poll的原理与select非常相似,差别如下:

  • 描述fd集合的方式不同,poll使用 pollfd 结构而不是select结构fd_set结构,所以poll是链式的,没有最大连接数的限制
  • poll有一个特点是水平触发,也就是通知程序fd就绪后,这次没有被处理,那么下次poll的时候会再次通知同个fd已经就绪。

select的几大缺点:

(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

(3)select支持的文件描述符数量太小了,默认是1024


细谈事件驱动-->epoll

epoll 提供了三个函数:

  • int epoll_create(int size);

    建立一個 epoll 对象,并传回它的id

  • int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

    事件注册函数,将需要监听的事件和需要监听的fd交给epoll对象

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

    等待注册的事件被触发或者timeout发生

epoll解决的问题:

  • epoll没有fd数量限制

    epoll没有这个限制,我们知道每个epoll监听一个fd,所以最大数量与能打开的fd数量有关,一个g的内存的机器上,能打开10万个左右

  • epoll不需要每次都从用户空间将fd_set复制到内核kernel

    epoll在用epoll_ctl函数进行事件注册的时候,已经将fd复制到内核中,所以不需要每次都重新复制一次

  • select 和 poll 都是主动轮询机制,需要遍历每一个人fd;

    epoll是被动触发方式,给fd注册了相应事件的时候,我们为每一个fd指定了一个回调函数,当数据准备好之后,就会把就绪的fd加入一个就绪的队列中,epoll_wait的工作方式实际上就是在这个就绪队列中查看有没有就绪的fd,如果有,就唤醒就绪队列上的等待者,然后调用回调函数。

  • 虽然epoll。poll。epoll都需要查看是否有fd就绪,但是epoll之所以是被动触发,就在于它只要去查找就绪队列中有没有fd,就绪的fd是主动加到队列中,epoll不需要一个个轮询确认。

    换一句话讲,就是select和poll只能通知有fd已经就绪了,但不能知道究竟是哪个fd就绪,所以select和poll就要去主动轮询一遍找到就绪的fd。而epoll则是不但可以知道有fd可以就绪,而且还具体可以知道就绪fd的编号,所以直接找到就可以,不用轮询。

总结

  • select, poll是为了解決同时大量IO的情況(尤其网络服务器),但是随着连接数越多,性能越差
  • epoll是select和poll的改进方案,在 linux 上可以取代 select 和 poll,可以处理大量连接的性能问题

select、poll和epoll的区别的更多相关文章

  1. [转载] select, poll和epoll的区别

    源地址:http://sheepxxyz.blog.163.com/blog/static/61116213201022003513530/ 随着2.6内核对epoll的完全支持,网络上很多的文章和示 ...

  2. Linux中select poll和epoll的区别

    在Linux Socket服务器短编程时,为了处理大量客户的连接请求,需要使用非阻塞I/O和复用,select.poll和epoll是Linux API提供的I/O复用方式,自从Linux 2.6中加 ...

  3. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...

  4. I/O复用中的 select poll 和 epoll

    I/O复用中的 select poll 和 epoll: 这里有一些不错的资料: I/O多路复用技术之select模型: http://blog.csdn.net/nk_test/article/de ...

  5. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  6. linux select poll and epoll

    这里以socket文件来阐述它们之间的区别,假设现在服务器端有100 000个连接,即已经创建了100 000个socket. 1 select和poll 在我们的线程中,我们会弄一个死循环,在循环里 ...

  7. 聊聊select, poll 和 epoll

    聊聊select, poll 和 epoll 假设项目上需要实现一个TCP的客户端和服务器从而进行跨机器的数据收发,我们很可能翻阅一些资料,然后写出如下的代码. 服务端 void func(int s ...

  8. Select,poll,epoll复用

    Select,poll,epoll复用 1)select模块以列表的形式接受四个参数,分别是可读对象,可写对象,产生异常的对象,和超时设置.当监控符对象发生变化时,select会返回发生变化的对象列表 ...

  9. select、pselect、poll和epoll的区别

    select.pselect.poll和epoll函数是unix中具有I/O复用的函数.什么是I/O复用?为什么要有I/O复用?以及在什么场合下使用I/O复用?既然都具有I/O复用的功能,那这几个函数 ...

  10. [转帖]select提高并发,select和poll、epoll的区别(杂)

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. https://www.2cto.com/kf/20161 ...

随机推荐

  1. NOIP2021T1报数——黄蓝紫黑的神奇梯度

    7A3T 点击查看代码 #include<iostream> #include<cstdio> #include<cmath> #include<algori ...

  2. pytest(8)-参数化

    前言 什么是参数化,通俗点理解就是,定义一个测试类或测试函数,可以传入不同测试用例对应的参数,从而执行多个测试用例. 例如对登录接口进行测试,假设有3条用例:正确账号正确密码登录.正确账号错误密码登录 ...

  3. Solution -「LOJ #141」回文子串 ||「模板」双向 PAM

    \(\mathcal{Description}\)   Link.   给定字符串 \(s\),处理 \(q\) 次操作: 在 \(s\) 前添加字符串: 在 \(s\) 后添加字符串: 求 \(s\ ...

  4. AI 神经网络理解

    神经网络理解 原文写于2019-12-05,2021-12-08改为markdown

  5. DubboSPI机制二之Dubbo中SPI初体验

    Dubbo高级之一SPI机制之JDK中的SPI - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中阐述了JDK标准的SPI,并对其应用做了相应的实践.在实际应用中,很多框架都会对其进行扩展 ...

  6. OpenGL ES 3D空间中自定义显示空间

    在Android中,我们所熟知的是在ES管线中,其在图元装配时,会进行图元组装与图元分配,这样就回剪裁出来视景体中的物体.但是如果我想在3D场景中规定一个区域,凡是在这个区域中的物体就能显示出来,非这 ...

  7. 商业智能BI工具为什么这么火?

    ​近年来,随着大数据.数据分析技术的兴起,商业智能BI工具应运而生,其中BI工具已成为众多企业商务决策的重要工具.也许有人会问,为什么企业需要商业智能BI工具?商业智能BI工具可以为企业带来什么? 首 ...

  8. Perforce 使用建议

    前言 楼主从事Unreal 游戏开发工作,使用VisualStudio 2019 /Rider/VisualStudio Code 开发过,使用Perforce版本管理对代码和资源进行管理. 主要想分 ...

  9. shell脚本的调试sh-x

    转至:https://blog.csdn.net/yjgithub/article/details/80908079 目录 一.简介 二.sh -x 脚本名.sh 三.set -x 一.简介 使用sh ...

  10. Docker入坑系列(一)

    Docker入坑系列(一) 引用嘛,当然是来引用别人说的东西啦. Docker 是一个开源项目,诞生于 2013 年初,它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux ...