Linux/Unix-五种IO模型

可参考书:UNIX网络编程卷1

1.阻塞IO(Blocking IO)

阻塞IO模型会一直等待数据准备好后再进行处理。当应用程序调用阻塞IO进行读取操作时,如果数据没有准备好,应用程序会一直阻塞等待,直到数据准备好才能继续执行后续操作。

2.非阻塞IO(Non-blocking IO)

非阻塞IO模型会立即返回,无论数据是否准备好。当应用程序调用非阻塞IO进行读取操作时,如果数据没有准备好,应用程序会立即返回一个错误码,而不会阻塞。应用程序可以继续执行其他操作,然后通过轮询或事件通知等方式来检查数据是否准备好。

3.IO复用(IO multiplexing)

IO复用模型使用select、poll或epoll等系统调用来同时监视多个文件描述符的就绪状态。当任何一个文件描述符就绪时,应用程序可以进行相应的读取操作。数据在就绪时可以立即处理。
在使用epoll进行IO操作时,以下是epoll的工作流程:

  1. 应用程序调用epoll_create()函数创建一个epoll文件描述符,用于管理IO事件。
  2. 应用程序使用epoll_ctl()函数将需要监听的文件描述符添加到epoll中,并指定感兴趣的事件类型(如可读、可写等)。
  3. 应用程序调用epoll_wait()函数等待IO事件的发生,该函数会阻塞,直到有事件发生或超时。
  4. 内核会监视被添加到epoll中的文件描述符,并在文件描述符上发生感兴趣的事件时,将这些事件加入到一个内核事件表中。
  5. 当有事件发生时,epoll_wait()函数会返回,并将就绪的文件描述符列表返回给应用程序。
  6. 应用程序可以遍历返回的就绪文件描述符列表,进行相应的IO操作,如读取数据、写入数据等。

在返回就绪的文件描述符列表时,epoll_wait()函数会提供一些额外的信息,如事件类型(可读、可写等)和事件数据(如可读数据的大小),以便应用程序更好地处理IO事件。
epoll的工作机制主要基于两个数据结构:红黑树和就绪链表。红黑树用于存储需要监视的文件描述符和事件,以便高效地进行查找和管理。就绪链表用于存储发生事件的文件描述符,以便在epoll_wait()函数返回时提供就绪的文件描述符列表。
通过使用epoll,内核能够高效地管理大量的并发连接,并且只返回就绪的文件描述符,避免了遍历整个文件描述符集合的开销。这使得epoll成为一种高性能的IO多路复用机制。 

4.信号驱动IO(Signal-driven IO)

信号驱动IO模型通过设置信号处理函数来处理数据。当数据就绪时,操作系统会发送一个信号给应用程序,通知它可以进行读取操作。应用程序在接收到信号后,可以在信号处理函数中进行数据的读取和处理。

5.异步IO(Asynchronous IO)

异步IO 是指发起输入之后 内核直接返回 等待内核把数据拷贝内用户态进程的时候 通知用户进程完成了。

异步IO模型允许应用程序发起IO操作后立即返回,并通过回调函数或事件通知机制来处理数据。当数据准备好后,操作系统会通知应用程序,应用程序可以调用回调函数或处理事件来读取和处理数据。

异步IO模型的工作流程如下:
  1. 应用程序发起异步IO操作,比如读取文件或网络数据。
  2. 内核接收到IO请求后,会立即返回,不会阻塞应用程序。
  3. 内核在后台进行IO操作,可以同时处理其他任务。
  4. 当IO操作完成时,内核会通知应用程序,通常通过回调函数或事件通知机制。
  5. 应用程序在接收到通知后,可以调用回调函数或处理事件,进行后续操作。

在异步IO模型中,应用程序不需要主动等待IO操作完成,而是通过内核的通知机制来得知IO操作的完成情况。这样可以提高应用程序的并发性能和响应能力,因为应用程序可以继续执行其他任务,而不需要阻塞等待IO操作完成。
需要注意的是,异步IO模型需要操作系统和编程语言的支持。在操作系统层面,需要提供异步IO的系统调用或API。在编程语言层面,需要提供相应的异步IO框架或库,以便开发者可以方便地使用异步IO模型。

总结

POSIX把这两个术语定义如下:

  1. 同步I/O操作 (synchronous I/O opetation) 导致请求进程阻塞,直到IO操作完成。
  2. 异步I/0操作 (asynchronous I/O opetation) 不导致请求进程阻塞。

阻塞式I/O模型、非阻塞式IO模型、I/O复用模型和信号驱动式I/O模型都是同步I/O模型,因为其中真正的I/O操作(recvfrom)将阻塞进程。只有异步IO模型与POSIX定义的异步IO相匹配。                             

不同IO模型对数据的处理方式会影响应用程序的编程模型和代码逻辑。阻塞IO和非阻塞IO通常需要应用程序主动检查数据是否就绪,而IO复用、信号驱动IO和异步IO则由操作系统或框架来通知应用程序数据的就绪状态。
posted @ 2019-07-11 16:43  GJH-  阅读(164)  评论(2)    收藏  举报