linux中poll和select有哪些区别

75次阅读
没有评论

共计 2837 个字符,预计需要花费 8 分钟才能阅读完成。

这篇文章主要讲解了“linux 中 poll 和 select 有哪些区别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着丸趣 TV 小编的思路慢慢深入,一起来研究和学习“linux 中 poll 和 select 有哪些区别”吧!

linux 中 poll 和 select 的区别是:select 单个进程所能打开的最大连接数由“FD_SETSIZE”宏定义,其大小是 32 个整数的大小,而 poll 因为采用链表存储,所以没有最大连接数的限制。

本教程操作环境:linux7.3 系统、Dell G3 电脑。

linux 中 poll 和 select 的区别

每个进程使用的 select 有最大连接数限制,只能有 FD_SETSIZE 个,而 poll 没有这样的限制(采用链表存储);

epoll 跟 select 都能提供多路 I / O 复用的解决方案。在现在的 Linux 内核里有都能够支持,其中 epoll 是 Linux 所特有,而 select 则应该是 POSIX 所规定,一般操作系统均有实现

select:

select 本质上是通过设置或者检查存放 fd 标志位的数据结构来进行下一步处理。这样所带来的缺点是:

1、单个进程可监视的 fd 数量被限制,即能监听端口的大小有限。

一般来说这个数目和系统内存关系很大,具体数目可以 cat /proc/sys/fs/file-max 察看。32 位机默认是 1024 个。64 位机默认是 2048.

2、对 socket 进行扫描时是线性扫描,即采用轮询的方法,效率较低:

当套接字比较多的时候,每次 select()都要通过遍历 FD_SETSIZE 个 Socket 来完成调度, 不管哪个 Socket 是活跃的, 都遍历一遍。这会浪费很多 CPU 时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是 epoll 与 kqueue 做的。

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

poll:

poll 本质上和 select 没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个 fd 对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有 fd 后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历 fd。这个过程经历了多次无谓的遍历。

它没有最大连接数的限制,原因是它是基于链表来存储的,但是同样有一个缺点:

1、大量的 fd 的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。

2、poll 还有一个特点是“水平触发”,如果报告了 fd 后,没有被处理,那么下次 poll 时会再次报告该 fd。

epoll:

epoll 有 EPOLLLT 和 EPOLLET 两种触发模式,LT 是默认的模式,ET 是“高速”模式。LT 模式下,只要这个 fd 还有数据可读,每次 epoll_wait 都会返回它的事件,提醒用户程序去操作,而在 ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无 论 fd 中是否还有数据可读。所以在 ET 模式下,read 一个 fd 的时候一定要把它的 buffer 读光,也就是说一直读到 read 的返回值小于请求值,或者 遇到 EAGAIN 错误。还有一个特点是,epoll 使用“事件”的就绪通知方式,通过 epoll_ctl 注册 fd,一旦该 fd 就绪,内核就会采用类似 callback 的回调机制来激活该 fd,epoll_wait 便可以收到通知。

epoll 为什么要有 EPOLLET 触发模式?

如果采用 EPOLLLT 模式的话,系统中一旦有大量你不需要读写的就绪文件描述符,它们每次调用 epoll_wait 都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率.。而采用 EPOLLET 这种边沿触发模式的话,当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完 (如读写缓冲区太小),那么下次调用 epoll_wait() 时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符

epoll 的优点:

1、没有最大并发连接的限制,能打开的 FD 的上限远大于 1024(1G 的内存上能监听约 10 万个端口);

2、效率提升,不是轮询的方式,不会随着 FD 数目的增加效率下降。只有活跃可用的 FD 才会调用 callback 函数;

即 Epoll 最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll 的效率就会远远高于 select 和 poll。

3、内存拷贝,利用 mmap()文件映射内存加速与内核空间的消息传递;即 epoll 使用 mmap 减少复制开销。

select、poll、epoll 区别总结:

1、支持一个进程所能打开的最大连接数

select

单个进程所能打开的最大连接数有 FD_SETSIZE 宏定义,其大小是 32 个整数的大小(在 32 位的机器上,大小就是 3232,同理 64 位机器上 FD_SETSIZE 为 3264),当然我们可以对进行修改,然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试。

poll

poll 本质上和 select 没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的

epoll

虽然连接数有上限,但是很大,1G 内存的机器上可以打开 10 万左右的连接,2G 内存的机器可以打开 20 万左右的连接

2、FD 剧增后带来的 IO 效率问题

select

因为每次调用时都会对连接进行线性遍历,所以随着 FD 的增加会造成遍历速度慢的“线性下降性能问题”。

poll

同上

epoll

因为 epoll 内核中实现是根据每个 fd 上的 callback 函数来实现的,只有活跃的 socket 才会主动调用 callback,所以在活跃 socket 较少的情况下,使用 epoll 没有前面两者的线性下降的性能问题,但是所有 socket 都很活跃的情况下,可能会有性能问题。

3、消息传递方式

select

内核需要将消息传递到用户空间,都需要内核拷贝动作

poll

同上

epoll

epoll 通过内核和用户空间共享一块内存来实现的。

总结:

综上,在选择 select,poll,epoll 时要根据具体的使用场合以及这三种方式的自身特点。

1、表面上看 epoll 的性能最好,但是在连接数少并且连接都十分活跃的情况下,select 和 poll 的性能可能比 epoll 好,毕竟 epoll 的通知机制需要很多函数回调。

2、select 低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善

感谢各位的阅读,以上就是“linux 中 poll 和 select 有哪些区别”的内容了,经过本文的学习后,相信大家对 linux 中 poll 和 select 有哪些区别这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是丸趣 TV,丸趣 TV 小编将为大家推送更多相关知识点的文章,欢迎关注!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-29发表,共计2837字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)