Unix下可用的五种 I/O 模型

介绍

当TCP客户端同时处理两个输入时:标准输入和TCP套接字,当客户端fgets(在标准输入上)被阻塞并且服务器进程被终止时,我们遇到了问题。服务器TCP正确地将FIN发送到客户端TCP,但由于客户端进程被禁止从标准输入读取,所以它从没有看到EOF,直到它从套接字读取(可能更晚)。

如果一个或多个I / O条件准备好(即,输入准备好被读取,或者描述符能够获得更多输出),我们希望得到通知。此功能称为 I/O 多路复用,由selectpoll函数以及前者的较新POSIX变体提供,称为pselect

在以下场景中,I / O复用通常用于网络应用程序:

  • 当客户端处理多个描述符(通常是交互式输入和网络套接字)时
  • 当客户端同时处理多个套接字时(这是可能的,但很少见)
  • 如果TCP服务器同时处理侦听套接字及其连接的套接字
  • 如果服务器同时处理TCP和UDP
  • 如果服务器处理多个服务并且可能处理多个协议

I / O复用不仅限于网络编程。许多重要的应用程序都需要这些技术。

I / O模型

我们首先检查Unix下可用的五种 I/O 模型的基本差异:

  • 阻塞I / O.
  • 非阻塞I / O.
  • I / O多路复用(selectpoll
  • 信号驱动I / O(SIGIO
  • 异步I / O(POSIX aio_函数)

输入操作通常有两个不同的阶段:

  1. 等待数据准备就绪。这涉及等待数据到达网络。当数据包到达时,它将被复制到内核中的缓冲区中。
  2. 将数据从内核复制到进程。这意味着将(就绪)数据从内核缓冲区复制到我们的应用程序缓冲区中

阻塞I / O模型

最流行的I / O模型是阻塞I / O模型(我们在前面的部分中使用了所有示例)。默认情况下,所有套接字都是阻塞的。场景如下图所示:

我们在这个例子中使用UDP而不是TCP,因为对于UDP,数据“准备好”读取的概念很简单:要么已经接收到整个数据报,要么没有接收到。使用TCP它会变得更复杂,因为插座的低水位标记等附加变量会起作用。

我们还将recvfrom系统调用称为区分我们的应用程序和内核,无论如何recvfrom实现(BSD getmsg上的系统调用和调用System V上的系统调用的函数)。通常会有一个从应用程序中运行到内核中运行的切换,之后会在一段时间后返回到应用程序。

在上图中,进程调用recvfrom和系统调用在数据报到达并复制到应用程序缓冲区之前不会返回,或者发生错误。最常见的错误是系统调用被信号中断。我们说过程从调用recvfrom到返回的整个时间都被阻止。当recvfrom成功返回时,我们的应用程序处理的数据包。

非阻塞I / O模型

当一个套接字设置为非阻塞时,我们告诉内核“当我请求的I / O操作无法在不使进程进入休眠状态时完成时,不要让进程进入休眠状态,而是返回错误”。该图如下:

  • 对于前三个recvfrom,没有数据要返回,内核立即返回错误EWOULDBLOCK
  • 我们第四次调用recvfrom,数据报就绪,它被复制到我们的应用程序缓冲区,并recvfrom成功返回。然后我们处理数据。

当一个应用程序坐在循环中调用recvfrom这样的非阻塞描述符时,它被称为轮询。应用程序不断轮询内核以查看某些操作是否已准备就绪。这通常是浪费CPU时间,但偶尔会遇到此模型,通常在专用于一个功能的系统上。

I / O多路复用模型

通过I / O多路复用,我们在这两个系统调用之一中调用selectpoll阻塞,而不是在实际的I / O系统调用中阻塞。该图是I / O复用模型的摘要:

我们阻塞调用select,等待数据报套接字可读。当select返回套接字可读时,我们然后调用recvfrom将数据报复制到我们的应用程序缓冲区中。

与阻塞I / O模型相比 *
  • 缺点:使用select需要两个系统调用(selectrecvfrom)而不是一个
  • 优点:我们可以等待多个描述符准备就绪(参见本章后面的select函数)
具有阻塞I / O的多线程 *

另一个密切相关的I / O模型是使用阻塞I / O的多线程。该模型非常类似于上面描述的模型,除了不使用select阻塞多个文件描述符,程序使用多个线程(每个文件描述符一个),然后每个线程可以自由调用阻塞系统调用recvfrom

信号驱动的I / O模型

信号驱动I / O模型使用的信号,告诉内核与通知我们SIGIO信号时,描述符已准备就绪。该图如下:

  • 我们首先为信号驱动的I / O启用套接字,并使用sigaction系统调用安装信号处理程序。此系统调用的返回是立即的,我们的过程继续进行; 它没有被阻止。
  • 当准备好读取数据报时,SIGIO将为我们的过程生成信号。我们可以:
    • 通过调用从信号处理程序读取数据报recvfrom,然后通知主循环数据已准备好处理
    • 通知主循环并让它读取数据报。

这个模型的优点是我们在等待数据报到达时不会被阻塞。主循环可以继续执行,只需等待信号处理程序通知数据已准备好处理或数据报已准备好被读取。

异步I / O模型

异步I / O由POSIX规范定义,并且已经协调了各种标准中出现的实时函数的各种差异,这些差异汇集在一起??形成当前的POSIX规范。

这些函数通过告诉内核启动操作并在整个操作(包括从内核到缓冲区的数据副本)完成时通知我们来工作。这个模型和信号驱动的I / O模型的主要区别在于,通过信号驱动的I / O,内核告诉我们何时可以启动I / O操作,但是使用异步I / O,内核告诉我们I / O操作完成时。请参见下图,例如:

  • 我们调用aio_read(POSIX异步I / O函数以aio_或开头lio_)并传递以下内核:

    • 描述符,缓冲区指针,缓冲区大小(相同的三个参数read),
    • 文件偏移量(类似于lseek),
    • 以及如何在整个操作完成时通知我们。

    此系统调用立即返回,并且在等待I / O完成时不会阻止我们的进程。

  • 我们假设在这个例子中,我们要求内核在操作完成时生成一些信号。在将数据复制到我们的应用程序缓冲区之前,不会生成此信号,这与信号驱动的I / O模型不同。

I / O模型的比较

下图是五种不同I / O模型的比较。

前四个模型之间的主要区别在于第一个阶段,因为前四个模型中的第二个阶段是相同的:recvfrom当数据从内核复制到调用者的缓冲区时,进程被阻塞。但是,异步I / O处理两个阶段,与前四个不同。

同步I / O与异步I /

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

  • 同步I / O操作会导致请求进程被阻塞,直到I / O操作完成。
  • 异步I / O操作不会导致请求进程被阻止。

使用这些定义,前四个I/O模型(阻塞,非阻塞,I/O多路复用和信号驱动I/O)都是同步的,因为实际的I/O操作(recvfrom)会阻止进程。只有异步I/O模型匹配异步I/O定义。

原文地址:https://www.cnblogs.com/rinack/p/10925484.html

时间: 2024-10-27 07:50:48

Unix下可用的五种 I/O 模型的相关文章

Unix下可用的5种IO模型

一.Unix可用的5种IO模型和区别: 1.阻塞式IO 2.非阻塞式IO 3.IO复用(select和poll) 4.信号驱动式IO(SIGIO) 5.异步IO(POSIX的aio_系列函数) 二.1.阻塞式IO模型: 最流行的IO模型是阻塞式IO模型 应用进程      内核 (recvfrom)------>系统调用--------->  无数据报准备好 | 等待数据 | 数据报准备好 | 将数据从内核复制到用户空间 | 处理数据报<-----返回成功指示<----- 复制完成

Unix系统的五种I/O模型

Unix下共有五种I/O模型: 1. 阻塞式I/O  2. 非阻塞式I/O  3. I/O复用(select和poll)  4. 信号驱动式I/O(SIGIO)  5. 异步I/O(POSIX的aio_系列函数)  io请求分两步: 1. 先将数据从存储介质(磁盘,网络等)拷贝到内核缓冲区,此时称为数据准备好,可以被用户应用程序读取. 2. 由用户应用程序拷贝内核缓冲区中的数据到用户缓冲区. ① 阻塞I/O模型            进程一直阻塞,直到数据拷贝完成 我们将函数recvfrom视为

Unix网络编程中的五种I/O模型_转

转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描述符.接受数据缓冲地址.大小传递给内核,但是如果此时 该与该套接口相应的缓冲区没有数据,这个时候就recvfrom就会卡(阻塞)在这里,知道数据到来的时候,再把数据拷贝到应用层,也就是传进来的地址空 间,如果没有数据到来,就会使该函数阻塞在那里,这就叫做阻塞I/O模型,如下图: 2. 非阻塞I/O模

[]转帖] 浅谈Linux下的五种I/O模型

浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html  一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer.如下图所示: 整个请求过程为: 用户进程发起请求,内核接受到请求后,从I/O设备中获取数据到buffer中,再将buffer中的数据copy到用户进程的地址空间,该用户进程获取到数

Windows Socket五种I/O模型——代码全攻略(转)

Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权.这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误.但功能强大.为了解决这个问题,提出了进行I/O操作的一些I/O模型,下面介绍最常见的三种: Windows Socket五种I/O模型——代码全攻

(转载)Windows Socket五种I/O模型——代码全攻略

如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的.Windows操作系统提供了选择(Select).异步选择(WSAAsyncSelect).事件选择(WSAEventSelect).重叠I/O(Overlapped I/O)和完成端口(Completion Port)共五种I/O模型.每一种模型均适用于一种特定的应用场景.程序员应该对自己的应用需求非常明确,而且综合考虑到程序的扩展性和可移植性等因素,作出自己的选择. 我会以一个回应反射式服务器(与<Windows网络

五种I/O模型的学习

来自   http://www.52im.net/thread-1935-1-1.html 4.互联网服务端处理网络请求的原理 首先看看一个典型互联网服务端处理网络请求的典型过程:<ignore_js_op> 由上图可以看到,主要处理步骤包括: 1)获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3): 2)构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4): 3)返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-

五种I/O模型简述

在说I/O模型之前,我们先来说说同步,异步,阻塞,非阻塞这四种调用方式的概念: 同步:在发出一个功能调用时,在没有得到结果之前,该调用就不返回,通俗点就是必须一件一件的做事,等这件事做完了才能做下一件事: 异步:异步和同步正好相对,当一个异步过程调用发出后,调用者不能立即得到结果,当该异步调用完成后,通过状态,通知和回调来通知调用者. 阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态之下,cpu不会给线程分配时间片,即线程暂停运行),函数只有在得到结果之后才

五种I/O模型

1.阻塞I/O     2.非阻塞I/O     3 .I/O复用(select和poll)   4.信号驱动I/O    5.异步I/O select函数I/O复用: select Function The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O. int select( __in int nfds, __in_o