轮询(poll)技术
下文将介绍Linux中的四种轮询技术,分别是:
- read
- select
- poll
- epoll
read
轮询技术对应于同步非阻塞I/O模型,每次轮询只能获知一个I/O操作对应的状态,轮询操作由用户负责。
select、poll、epoll 轮询技术对应于I/O多路复用(I/O Multiplexing),每次轮询可检测多个I/O操作的状态,轮询(poll)操作由操作系统负责(而用户线程调用对应的轮询函数时会被阻塞)。
注意:
- 以下这些轮询技术都分别对应一种逻辑上的轮询方法(Function)。而每一种轮询方法,内核都会以系统调用(本质是一个或一系列的C语言函数)的形式提供给用户线程进行调用;
- 轮询技术仅仅描述了当用户已经发起I/O操作后,从“用户线程获取这些I/O操作是否已经完成”的过程;
- 这些轮询技术对应的轮询方法都会阻塞用户线程。换句话说,若所有监听的 fd 对应的I/O操作在很长时间内都没有完成,在这段时间内,这些轮询方法都不会返回控制流给用户线程。
同步非阻塞I/O模型
read
Refer to https://swsmile.info/post/linux-io-polling-read/
I/O多路复用(I/O Multiplexing)
我们希望,用户线程不需要进行不停的轮询,以避免消耗额外的CPU资源。同时,在数据就就绪时,用户线程处于休眠状态(sleep)。而当一个或多个 fd 对应的I/O操作数据准备完成时,用户线程被唤醒,并去处理这些I/O操作。
I/O多路复用(I/O Multiplexing)技术正是为了满足上面的需求而诞生的。I/O多路复用基于同步非阻塞模型(Synchronous non-blocking model)+ 轮询技术(poll)。
I/O多路复用使得用户线程可以并发的阻塞在多个 fd 上,当其中任何一个 fd 对应的I/O操作准备就绪时,控制流被返回给用户线程,用户线程从 sleep状态切换成ready状态。
I/O多路复用从技术实现上又分很多种,在Linux中,包括select、poll和epoll,我们逐一来看看I/O多路复用各种实现方式的优劣。
select
Refer to https://swsmile.info/post/linux-io-polling-select/
poll
Refer to https://swsmile.info/post/linux-io-polling-poll/
epoll
Refer to https://swsmile.info/post/linux-io-polling-epoll/
总结
在同步非阻塞I/O中,需要使用轮询技术。虽然在用户线程发起I/O操作(Operation)后,用户线程不会被阻塞。因此,虽然理论上,此时用户线程可以去处理其他任务;但事实上,用户线程仍然需要去执行轮询,以确认I/O操作是否完成了(若完成了,则执行对应的后续操作)。
而I/O多路复用对应的轮询技术对应的轮询方法(select,poll,epoll)都会阻塞用户线程。换句话说,若所有监听的 fd 对应的I/O操作在很长时间内都没有完成,在这段时间内,这些轮询方法都不会返回控制流给用户线程。
Reference
- 《Unix Network Programming, Volume 1: The Sockets Networking API: Sockets Networking API》
- 《Linux System Programming Talking Directly to the Kernel and C Library》
- I/O Multiplexing - http://www.cs.toronto.edu/~krueger/csc209h/f05/lectures/Week11-Select.pdf
- 6.2. Waiting for I/O - http://faculty.salina.k-state.edu/tim/ossg/Device/io_wait.html
- The method to epoll’s madness - https://medium.com/@copyconstruct/the-method-to-epolls-madness-d9d2d6378642
- Overview of Blocking vs Non-Blocking - https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/
- Chapter 6. I/O Multiplexing: The select and poll Functions - https://notes.shichao.io/unp/ch6/
- Synchronous and Asynchronous I/O - https://docs.microsoft.com/en-us/windows/desktop/fileio/synchronous-and-asynchronous-i-o
- non-blocking IO vs async IO and implementation in Java - https://stackoverflow.com/questions/25099640/non-blocking-io-vs-async-io-and-implementation-in-java
- https://www.rubberducking.com/2018/05/the-various-kinds-of-io-blocking-non.html
- https://jvns.ca/blog/2017/06/03/async-io-on-linux--select--poll--and-epoll/