> 文章列表 > Linux上的五种IO模型

Linux上的五种IO模型

Linux上的五种IO模型

阻塞、非阻塞、同步、异步

典型的一次IO的两个阶段数据准备数据读写

数据准备:根据系统IO操作的就绪状态

  • 阻塞
  • 非阻塞

数据读写:根据应用程序和内核的交互方式

  • 同步
  • 异步

在处理 IO 的时候,阻塞和非阻塞都是同步 IO。只有使用了特殊的 API 才是异步IO。

在这里插入图片描述

数据就绪阶段分为阻塞和非阻塞。表现得结果就是,阻塞当前线程或是直接返回。

IO的同步和异步

  • 同步:数据读写还是应用程序自己读(阻塞),TCP内核缓冲区—> 应用程序缓冲区buf

    char buf[1024] = {0}int size = recv(sockfd, buf, 1024, 0)
    

注:size == -1 && errno == EAGAIN 表示没有数据接收到,但是正常

相当于买车票,车站出票你要自己去买票

  • 异步

调用异步IO函数,由系统将数据搬到buf,然后用一个sigio通知。应用程序自己工作(是否是多线程了?)aio_readaio_write

相当于买车票,车站出票直接寄给你。

Node.js 是基于异步非阻塞模式下的高性能服务重器

五种IO模型

建议如下五种模型能背会并且在纸上默写出来

阻塞blocking

在这里插入图片描述

非阻塞 non-blocking IO

在这里插入图片描述

注意到数据读写阶段仍需应用进程阻塞读取数据。

IO复用(IO multiplexing)

在这里插入图片描述

可同时监视多个socket的数据就绪状态,但数据读写阶段仍需应用进程阻塞读取数据。

信号驱动(signal-driven)

在这里插入图片描述

内核在第一个阶段是异步,在第二个阶段是同步;

与非阻塞IO的区别在于它提供了消息通知机制,不需要用户进程不断的轮询检查,减少了系统API的调用次数,提高了效率。

异步(asynchronous)

数据就绪阶段后的数据读写由系统代为将数据从内核空间拷贝到用户空间。

在这里插入图片描述

struct aiocb {int aio_fildesoff_t aio_offsetvolatile void *aio_bufsize_t aio_nbytesint aio_reqpriostruct sigevent aio_sigeventint aio_lio_opcode
}

参考资料

  1. 陈硕.《Linux多线程服务端编程》
  2. 施磊. 手写muduo网络库项目