Linux中select poll和epoll的区别

Linux中select poll和epoll的区别,第1张

============select、poll、epoll之间的区别=================

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,

可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),

能够通知程序进行相应的读写 *** 作,读写过程是阻塞的,

select的几大缺点:监视的文件描述符的数量存在最大限制

1 单个进程可监视的fd数量被限制

2 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大

3 对socket进行扫描时是线性扫描

//select的3个缺点:1 连接数受限 2 查找配对速度慢 3 数据由内核拷贝到用户态。

poll的实现和select非常相似,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)

select、poll的内部实现机制相似,它没有最大连接数的限制,原因是它是基于链表来存储的,

但是同样有一个缺点:大量的fd的数组被整体复制于用户态和内核地址空间之间,

而不管这样的复制是不是有意义。它将用户传入的数组拷贝到内核空间,

然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,这过程经历了多次无谓的遍历

epoll是对select和poll的改进

epoll:IO的效率不会随着监视fd的数量的增长而下降。epoll不同于select和poll轮询的方式,

而是通过每个fd定义的回调函数来实现的。只有就绪的fd才会执行回调函数。

一般情况下fd数量较少的时候poll略优于epoll,但是当fd增大到某个阈值时,

poll性能急剧下降。而epoll始终保持的稳定的性能。

希望采纳

本序列涉及的 Linux 源码都是基于 linux-4.14.143 。

1.1 文件抽象

在 Linux 内核里,文件是一个抽象,设备是个文件,网络套接字也是个文件。

文件抽象必须支持的能力定义在 file_operations 结构体里。

在 Linux 里,一个打开的文件对应一个文件描述符 file descriptor/FD,FD 其实是一个整数,内核把进程打开的文件维护在一个数组里,FD 对应的是数组的下标。

文件抽象的能力定义:

1.2 文件 poll *** 作

poll 函数的原型:

文件抽象 poll 函数的具体实现必须完成两件事(这两点算是规范了):

1. 在 poll 函数敢兴趣的等待队列上调用 poll_wait 函数,以接收到唤醒;具体的实现必须把 poll_table 类型的参数作为透明对象来使用,不需要知道它的具体结构。

2. 返回比特掩码,表示当前可立即执行而不会阻塞的 *** 作。

下面是某个驱动的 poll 实现示例,来自:https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch05s03.html:

poll 函数接收的 poll_table 只有一个队列处理函数 _qproc 和感兴趣的事件属性 _key。

文件抽象的具体实现在构建时会初始化一个或多个 wait_queue_head_t 类型的事件等待队列 。

poll 等待的过程:

事件发生时的唤醒过程:

一个小困惑:

fds[0].fd 与 fds[1].fd 同样是sock这个描述符, 其中在fds[0] 中注册POLLIN和POLLRDNORM事件,

在fds[1]中监听POLLOUT和POLLWRNORM事件, 这样做就成功了, 不会出现上述 "同时在一个sock描述符注册可读可写事件,

导致监听结果与实际不符"的现象。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/7152944.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-02
下一篇2023-04-02

发表评论

登录后才能评论

评论列表(0条)

    保存