Linux的五种IO模型

众所周知,出于对 OS 安全性的考虑,用户进程是不能直接操作 I/O 设备的。必须通过系统调用请求操作系统内核来协助完成 I/O 动作。

下图展示了 Linux I/O 的过程。
在这里插入图片描述
操作系统内核收到用户进程发起的请求后,从 I/O 设备读取数据到 kernel buffer 中,再将 buffer 中的数据拷贝到用户进程的地址空间,用户进程获取到数据后返回给客户端。

在 I/O 过程中,对于输入操作通常有两个不同的阶段:

  1. 等待数据准备好
  2. 将数据从内核缓冲区拷贝到用户进程

根据这两个阶段等待方式的不同,可以将 Linux I/O 分为 5 种模式:

  1. blocking I/O,阻塞式 I/O
  2. nonblocking I/O,非阻塞式 I/O
  3. I/O multiplexing(select and poll),I/O 多路复用
  4. signal driven I/O(SIGIO),信号驱动 I/O
  5. asynchronous I/O(the POSIX aio_functions),异步 I/O

对于 Socket 上的输入操作:

  1. 第 1 步通常是等待网络上的数据到达。当数据包到达时,它被复制到内核的缓冲区中。
  2. 第 2 步是从内核缓冲区复制数据到应用程序缓冲区。

下面详细介绍 Linux 中的 5 种 I/O 模式。
1. Blocking I/O

默认情况下,所有的 Socket 都是阻塞式的。下图展示了一个基于 UDP 的网络数据获取流程。

用户进程调用了 recvfrom 系统调用,此后一直处于等待状态,直到数据包到达并被拷贝到应用程序缓冲区,或者发生 error 才返回。整个过程从开始 recvfrom 调用到它返回一直处于阻塞状态。当 recvfrom 调用返回后,应用进程才能处理数据。
在这里插入图片描述

2. Nonblocking I/O

可以设置 Socket 为非阻塞模式。这种设置相当于告诉内核“当 I/O 操作时,如果请求是不可能完成的,不要把进程进入睡眠状态,返回一个错误即可“。下图展示了整个流程:在前三次调用 recvfrom 系统调用时,没有就绪的数据返回,所以内核立即返回 EWOULDBLOCK 错误。第四次调用 recvfrom 时,数据报已经准备好,它被复制到应用程序缓冲区中,然后 recvfrom 成功返回。最后应用进程对数据进行处理。当应用程序在一个非阻塞描述符上循环调用 recvfrom 系统调用时,这种方式也被称为轮询。应用程序不断轮询内核,以查看是否有某些操作准备好了。很明显,这通常会浪费 CPU 时间,但这种模式偶尔也会被使用。通常在专门用于一个功能的系统上使用。
在这里插入图片描述

3. I/O Multiplexing

I/O 多路复用通常使用 select 或者 poll 或者 epoll 系统调用。这种方式下的阻塞只是被 select 或者 poll 或者 epoll 系统调用阻塞,而不会阻塞实际的 I/O 系统调用(即数据输入、输出不会被阻塞)。下图展示了整个过程。当调用 select 时,应用进程被阻塞。同时,系统内核会“监视”所有 select 负责的 Socket。只要其中有 1 个 Socket 的数据准备好了,select 调用就返回。然后调用 recvfrom 将数据报复制到应用程序缓冲区,最后返回给用户进程。

乍一看,这种方式和 blocking I/O 相比似乎更差,因为整个过程产生了 2 次系统调用,select 和 recvfrom。但是使用 select 的好处是可以同时等待多个描述符准备好。换句话说可以同时“聆听”多个 Socket 通道,同时处理多个连接。select 的优势不是对于单个连接处理得更快,而是能同时处理更多的连接。这和多线程阻塞式 I/O 有点类似。只不过后者是使用多个线程(每个文件描述符对应一个线程)来处理 I/O,每个线程都可以自由地调用阻塞式系统调用,比如 recvfrom。我们知道线程多了会带来上下文切换的开销,因此未必优于 select 方式。在前面 Java NIO 的例子中,我们已经体会到了 selector 带来的性能提升。
在这里插入图片描述
Linux 内核将所有外部设备都当成一个个文件来操作。我们对文件的读写都通过调用内核提供的系统调用;内核给我们返回一个文件描述符(file descriptor)。而对一个 Socket 的读写也会有相应的描述符,称为 socketfd。应用进程对文件的读写通过对 fd 的读写完成。

4. Signal Driven I/O

信号驱动方式就是等数据准备好后,由内核发出 SIGIO 信号通知应用进程。示意图如下:
在这里插入图片描述
应用进程通过 sigaction 系统调用建立起 SIGIO 信号处理通道,然后此系统调用就返回,不阻塞。当数据准备好后,内核会产生一个 SIGIO 信号通知到应用进程。此时既可以使用 SIGIO 信号处理器通过 recvfrom 系统调用读取数据,然后通知应用进程数据准备好了,可以处理了;也可以直接通知应用进程读取数据。不管使用何种方式,好处都是应用进程不会阻塞,可以继续执行,只要等待信号通知数据准备好被处理了、数据准备好被读取了。

5. asynchronous I/O

异步 I/O 是由 POSIX 规范定义的。和信号驱动 I/O 模型的区别是前者内核告诉我们何时可以开始一个 I/O 操作,而后者内核会告诉我们一个 I/O 操作何时完成。示意图如下:
在这里插入图片描述

当用户进程发起系统调用后会立刻返回,并把所有的任务都交给内核去完成,不会被阻塞等待 I/O 完成。内核完成之后,只需返回一个信号告诉用户进程已经完成就可以了。

五种 I/O 模式可以从同步、异步,阻塞、非阻塞两个维度来划分:
在这里插入图片描述


引用:https://zhuanlan.zhihu.com/p/543661648

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/219268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【超详细】创建vue3+ts项目(引入ElementPlus、Axios)

目录 前言1、使用vue脚手架创建项目1.1检查vue版本1.2 使用vue脚手架创建项目 2、删除项目多余文件,修改配置项目2.1、删除以下文件2.1、在views下创建index文件2.2、修改router/index.ts路由文件:2.3、修改App.vue文件:2.4、初始化页面样式以…

LeetCode141. Linked List Cycle

文章目录 一、题目二、题解 一、题目 Given head, the head of a linked list, determine if the linked list has a cycle in it. There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next poi…

windows上抓包出现大包未分片以及关闭tso方法

wireshark抓包中会有大数据包(未分片包)和ip校验和不对的包,问题根因在目前很多电脑网卡支持TSO和将校验和计算到网卡上,导致抓出数据包未分片 详细文章看: https://www.cnblogs.com/charlieroro/p/11363336.html 目前很多网卡已…

业务代码-整合框架-存储-缓存常见错误详解一

一. java空指针和异常: 1.什么是空指针异常(java.lang.NullPointException): 1.1常见的空指针异常案例: public class WhatIsNpe {public static class User {private String name;private String[] address;public void print…

项目一 分析并设计学生管理数据库

项目一 分析并设计学生管理数据库 1,做好管理数据库的知识准备 1.1,初识数据库 **1,DBMS:**数据库管理系统(Database Management System)。数据库 是通过DBMS创建和操作的 容器。 **2,DB:**数据库(data…

Python入门第2篇(pip、字符串、方法、json、io操作)

目录 pip包管理器 字符串 方法 json 文件操作 pip包管理器 包管理器类似.NET下的nuget,主要用于管理引用依赖项。 安装Python的时候,已经默认安装了pip包管理器,因此无需单独安装 cmd,输入:pip --version 显示…

C语言:高精度加法

P1601 AB Problem&#xff08;高精&#xff09; - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 过大的数计算就无法用变量定义计算&#xff0c;但可以用数组巧妙的化解这个问题。 #include<stdio.h> #include<stdlib.h> #include<string.h> char x[10005];…

004 Windows NTFS文件夹权限

一、NTFS文件权限&#xff1a; NTFS&#xff08;New Technology File System&#xff09;是Windows NT内核的系列操作系统支持的、一个特别为网络和磁盘配额、文件加密等管理安全特性设计的磁盘格式&#xff0c;提供长文件名、数据保护和恢复&#xff0c;能通过目录和文件许可…

ffmpeg编解码——数据包(packet)概念(如何正确处理数据包中的显示时间戳pts与解码时间戳dts关系?)

文章目录 FFmpeg编解码——数据包&#xff08;Packet&#xff09;概念1. 数据包&#xff08;Packet&#xff09;简介2. 数据包&#xff08;Packet&#xff09;在FFmpeg中的应用2.1 从媒体文件读取数据包2.2 向媒体文件写入数据包 3. 数据包&#xff08;Packet&#xff09;相关问…

【Docker】学习笔记(三)三剑客之 docker-compose文件书写项目多服务容器运行

简介 引言&#xff08;需求&#xff09; 为了完成一个完整项目势必用到N多个容器配合完成项目中的业务开发&#xff0c;一旦引入N多个容器&#xff0c;N个容器之间就会形成某种依赖&#xff0c;也就意味着某个容器的运行需要其他容器优先启动之后才能正常运行&#xff1b; 容…

策略模式实现

策略模式: 策略模式是一种行为型设计模式&#xff0c;它允许你定义一系列算法&#xff0c;把它们封装起来&#xff0c;并且使它们可以互相替换。这样&#xff0c;使用算法的客户端代码可以独立于具体的算法实现方式。 就好像是你要去旅行&#xff0c;你可以选择多种不同的交通…

【EI会议征稿中|IEEE出版】第三届信息技术与当代体育国际学术会议(TCS 2023)

【IEEE出版】第三届信息技术与当代体育国际学术会议&#xff08;TCS 2023&#xff09; 2023 3rd International Conference on Information Technology and Contemporary Sports 2023年第三届信息技术与当代体育国际学术会议&#xff08;TCS 2023&#xff09;将于2023年12月2…

Dueling DQN 跑 Pendulum-v1

gym-0.26.1 Pendulum-v1 Dueling DQN 因为还是DQN,所以我们沿用double DQN,然后把 Qnet 换成 VAnet。 其他的不变&#xff0c;详情参考前一篇文章。 class VA(nn.Module):"""只有一层隐藏层的A网络和V网络"""def __init__(self, state_dim, hidd…

子目录文件夹图片汇总

import os import shutildef collect_images(source_folder, target_folder):# 遍历主文件夹及其所有子文件夹for root, dirs, files in

位1的个数

题目链接 位1的个数 题目描述 注意点 输入必须是长度为 32 的 二进制串 解答思路 位运算判断每一位是否为1 代码 public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {int res 0;for (int i 0; i < 32; i) {res …

项目经理和产品经理该如何选择?

最近很多人咨询“项目经理跟产品经理该怎么选&#xff0c;我更适合哪个&#xff1f;”“项目经理跟产品经理哪个更有钱途 ”“项目经理转产品经理好转吗”等等&#xff0c;今天就一次性说清楚项目经理跟产品经理有什么区别&#xff0c;应该怎么选择。 不想看长篇大论的&#x…

Python+Pytest接口自动化之HTTP协议基础

HTTP协议简介 HTTP 即 HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09;&#xff0c;是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。 设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。HTTP 协议在 OSI 模型…

Kubernetes版本升级到v1.18.0方法

升级k8s版本才能使用kube-prometheus安装监控 1、查看集群状态 [rootk8s-master k8s-script]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready master 5d22h v1.18.0 k8s-slave1 Ready <none> 4d10h v1.18.0 k…

ActiveMQ使用指南

介绍 ActiveMQ是Apache开源组织旗下的一个项目&#xff0c;是一个流行的开源消息中间件。它完全支持JMS1.1和J2EE1.4规范的JMS Provider实现&#xff0c;并且是纯Java开发的产品。ActiveMQ支持多种语言编写客户端&#xff0c;包括C,C,C#,Perl,PHP,Ruby,Ajax等&#xff0c;同时…

php5, php7,php8 有什么区别

PHP 5、PHP 7 和 PHP 8 是 PHP 编程语言的不同版本&#xff0c;它们之间有许多改进和变化。以下是它们的一些主要区别&#xff1a; 1. 性能提升&#xff1a; PHP 5&#xff1a; PHP 5.x 版本的性能相对较低&#xff0c;特别是在处理大量并发请求和执行大型应用程序时。 PHP 7…