select、poll和epoll的区别

news/2024/7/9 18:20:25 标签: 操作系统, epoll, 内核

操作系统在处理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,可以处理大量连接的性能问题

http://www.niftyadmin.cn/n/762622.html

相关文章

MySQL-InnoDB-MVCC多版本并发控制

前言 最近正在啃《高性能MySQL》这本书, 当看到事务相关知识时,决定对该知识点稍微深入一下, 《高性能MySQL》中在介绍事务相关知识点时, 显然不是特别深入, 很多比较底层的知识点并没有太多的深入, 当然此处并不是要对本书做什么评判,言归正传, 这里主要先说一下本人在啃相关…

matlab怎么把音频变成信号_信号在脑子里面应该是什么样的(二)

上节我们讲的主要观点是:信号在我们脑海里面应该是以频谱的方式呈现,也就是各种频率的正弦波。原因也说了,电感和电容的阻抗公式只能适用于正弦波。而正巧的是,傅里叶变换能将任何信号都变成正弦波的叠加。因此,我们处…

MySQL的可重复读级别能解决幻读吗

引言 之前在深入了解数据库理论的时候,了解到事物的不同隔离级别可能存在的问题。为了更好的理解所以在MySQL数据库中测试复现这些问题。关于脏读和不可重复读在相应的隔离级别下都很容易的复现了。但是对于幻读,我发现在可重复读的隔离级别下没有出现&…

lrange是取出所有值并移除么_惠安21岁小伙眼睛插入1.5cm码钉,TA们为他取出“眼中钉”!...

21岁的复合门工匠在作业时,右眼不慎插入弹起的码钉,医生夜里急诊为其取出眼球壁码钉约1.5cm长。日前,惠安的复合门工匠小许在修门边的时候,一颗弹飞起来的码钉插入他的眼内,顿时他的右眼疼痛难忍,睁不开&am…

数据库查询优化的12种方式

查询优化方式: 1 硬件层的优化 1 CPU: 个数 / 核数 / 频率 / 线程数 / 一级 cache/ 二级 cache 2 内存 : 容量与 64-bits/ 带宽 3 I/O: seek(>100 次 / 秒 )/read/write(>10–20MB/s) 4 网络 : 带宽 / 传输协议 2 存储引擎优化 1 InnoDB : 1) i…

没有忽略此网络_你有过手机信号满格但却没有移动网络?三个办法可以顺利解决...

在移动互联网的今天,手机的网络变得至关重要。从3g到现在的5g,网速越来越快。而我们对网络的需求也越来越重,甚至可以说万物基于移动互联网。但有时候我们也会经常遇到一些这样的状况。在某个场景需要使用移动网络时,明明信号满格…

Java String源码分析

什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不…

jtopo node.text换行_求助:jtopo node文字换行问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼在jtopo 生成前,粘贴以下代码CanvasRenderingContext2D.prototype.wrapText function(str,x,y){var textArray str.split(\n);if(textArrayundefined||textArraynull)return false;var rowCnt textArray.length;var …