BruceBat's Blog
BruceBat's Blog

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生


  • 首页

  • 归档

  • 分类

  • 标签

  • 搜索
NIO I/O 计算机科学 操作系统 设计模式 随记 WebSocket 计算机网络 注册中心 经典电影 xxl-job 分布式 分布式任务调度 MySQL DevOps Docker 多线程 有趣的问题 Mybatis-Plus Mybatis Java 数据结构

有趣的操作系统:文件IO和网络IO

发表于 2021-10-23 | 0 | 阅读次数 583
“

人生苦短,不如养狗

”

一、从I/O开始

  在学习和使用计算机的过程中基本绕不开这样一个概念—— I/O ,也即输入/输出,指的是一切操作、程序或设备与计算机之间发生的数据传输过程。

  对于计算机而言, I/O操作 和 计算处理 是贯穿它一生的两大主要任务,其中大多数时间都是在执行I/O操作。这里所说的I/O操作实际上分为硬件和软件两个部分,分别是I/O设备和I/O子系统。

I/O设备

  时至今日,I/O设备的种类愈加繁多,从功能上(或者说工作方式上)可以对这些设备进行如下划分:

  • 存储设备 : 又叫块设备,这类设备将信息存储在固定大小的块当中,每个块都有自己的地址,且每块都能独立于其他块进行读写。较为常见的存储设备有磁盘、磁带。
  • 传输设备 : 又叫网络通信设备,这类设备主要用于与远程设备进行通信,常见的传输设备有网卡、Modem。
  • 人机交互设备 : 又叫字符设备,这类设备在I/O传输过程以字符为单位进行信息的传输。较为常见的字符设备有屏幕、键盘、鼠标,由于字符设备是直面用户的设备,且通过这些设备用户能够和计算机产生交互,所以这类设备又叫人机交互设备。
  • 特殊设备 : 除了上述三种设备以外的可以进行I/O传输的设备都可以归类为特殊设备。

  可以看到I/O设备种类繁杂,且彼此之间存在很大差异。为了对上层应用程序屏蔽底层设备的差异和细节,同时为了进行硬件和软件接口的标准化,操作系统内核设计成使用 设备驱动程序模块 的结构。设备驱动程序为I/O子系统提供了统一的设备访问接口,就像系统调用为应用程序与操作系统之间提供了统一的标准接口。但同时需要注意一点,I/O设备和设备驱动程序(计算机)的通信实际上是通过 硬件接口(端口) 来完成的,这一过程需要软硬件共同合作才能完成。

I/O接口(I/O子系统)

  再华丽的硬件如果没有对应匹配的软件提供控制管理的能力,硬件本应该提供的服务将最终无法得到使用。就如上文所说的,对与计算机相连设备(I/O设备)的控制是操作系统的主要任务之一,而这些用于控制设备的多种方法的集合就构成了 I/O子系统 。

  正如上面所说的,随着I/O设备的不断发展,I/O设备的种类愈加繁多,如果没有标准的、抽象的I/O操作接口,就会导致新类型的I/O很难接入操作系统。为了屏蔽底层硬件设备的差异和细节,操作系统使用设备驱动程序来抽象和统一了设备的访问接口,具体的实现由硬件设备的厂商自行实现。(可以看到,面向抽象编程的思想很早就兴起了)

  聊完了I/O的一些基本概念,下面我们来看一看在日常开发过程中经常会遇到的两个概念: 文件I/O 和 网络I/O 。

二、文件I/O

  我们即将讨论的 文件I/O 这一概念更多偏向于软件层面,也即操作系统层面。在操作系统当中,为了方便用户或者开发人员对于数据信息(由外设提供)的使用,操作系统对存储设备的各种属性加以抽象,从而定义了逻辑存储单元(文件),再将文件映射到物理设备上。需要注意的是,文件的概念不仅适用于存储设备,还适用于其他I/O设备,两者的区别在于文件类型和操作系统对于两种不同类型文件的操作。这也验证了Linux当中的一句话:“一切皆文件”。(这里再一次出现了面向对象的设计理念)这里我们只单纯讨论存储设备相关的文件I/O概念。

  从上图可以看到,如果一个应用程序想要发起一个文件I/O请求需要通过操作系统当中的文件系统来完成对应的I/O操作。上面我们也提到了,操作系统提供给用户可以操作的逻辑存储单元为文件(在UNIX环境中使用了 文件描述符 这样一个概念),这个可以操作的文件对象包含了实际被操纵对象的基本属性,操作系统将其抽象为文件属性,比如名称、标识符、类型、位置、大小、保护、用户标识以及时间等信息。针对文件这样一个抽象数据类型,文件系统提供了创建、写、度、定位、删除和截短等系统调用。

  如果我们将文件I/O的概念进一步限制到Linux环境中,又可以将其成为低级磁盘I/O,任何兼容POSIX标准的操作系统都能够支持文件I/O。同时文件I/O能够访问存储设备当中不同类型的文件,但是访问文件时并不会通过缓冲区,而是会直接通过系统调用进行对应资源的访问。

三、网络I/O

  我们日常讨论的网络通信本质上就是网络I/O,通过网络I/O,我们可以和远程设备进行通信(数据交换)。由于网络I/O和正常的磁盘I/O在性能和访问方式上有较大的差异,所以针对磁盘I/O的读写方法也就无法适用于网络I/O身上,大部分操作系统针对网络I/O抽象除了一套特殊的接口—— 网络Socket接口 ,用于对网络I/O进行操作。当然,上面也说了,在Linux当中“一切皆文件”,为了统一概念,Socket在Linux当中也是通过文件描述符来进行描述的,只不过这个文件描述符描述的不是本地文件,而是远程设备对应的文件。

  由于网络通信存在不可预知的问题,所以诞生了诸多I/O模型,这些I/O模型本质上是一种客户端(或者说是服务消费者)对网络I/O请求的处理方式。由于网络上这类资料还是非常多的,这里就不铺开描述了。

四、总结

  从大的概念来看,文件I/O和网络I/O本质上都是对资源的访问,只不过一个是本地设备,一个是远程设备。但是从访问方式和性能上来看,文件I/O和网络I/O无论是在I/O接口和系统调用上都有很大差别。

brucebat wechat
一个闲鱼程序猿的微信公众号
  • 本文作者: brucebat
  • 本文链接: https://www.swzgeek.com/archives/有趣的操作系统文件io和网络io
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# NIO # I/O # 计算机科学 # 操作系统 # 设计模式 # 随记 # WebSocket # 计算机网络 # 注册中心 # 经典电影 # xxl-job # 分布式 # 分布式任务调度 # MySQL # DevOps # Docker # 多线程 # 有趣的问题 # Mybatis-Plus # Mybatis # Java # 数据结构
探秘Java:“润物细无声”的Java Agent
那些你学了又忘的Java I/O(一):总览
  • 文章目录
  • 站点概览
brucebat

brucebat

一个有梦想的咸鱼程序猿

46 日志
8 分类
22 标签
RSS
Github E-mail
Creative Commons
© 2020 — 2023 brucebat
苏ICP备20002207号-1

苏公网安备 32011302320859号

0%