【Linux】I/O轮询技术

Posted by 西维蜀黍 on 2019-01-19, Last Modified on 2022-12-10

轮询(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