百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

完了,这个硬件成精了,它竟然绕过了 CPU

myzbx 2025-04-24 05:36 9 浏览

这是 Linux 系列第三篇文章,系列文章请查阅

Linux 操作系统!开篇

Linux 进程必知必会

我们之前了解过了 Linux 的进程和线程、Linux 内存管理,那么下面我们就来认识一下 Linux 中的 I/O 管理。

Linux 系统和其他 UNIX 系统一样,IO 管理比较直接和简洁。所有 IO 设备都被当作文件,通过在系统内部使用相同的 read 和 write 一样进行读写。

Linux IO 基本概念

Linux 中也有磁盘、打印机、网络等 I/O 设备,Linux 把这些设备当作一种 特殊文件 整合到文件系统中,一般通常位于 /dev 目录下。可以使用与普通文件相同的方式来对待这些特殊文件。

特殊文件一般分为两种:

块特殊文件是一个能存储固定大小块信息的设备,它支持以固定大小的块,扇区或群集读取和(可选)写入数据。每个块都有自己的物理地址。通常块的大小在 512 - 65536 之间。所有传输的信息都会以连续的块为单位。块设备的基本特征是每个块都较为对立,能够独立的进行读写。常见的块设备有 硬盘、蓝光光盘、USB 盘与字符设备相比,块设备通常需要较少的引脚。

块特殊文件的缺点基于给定固态存储器的块设备比基于相同类型的存储器的字节寻址要慢一些,因为必须在块的开头开始读取或写入。所以,要读取该块的任何部分,必须寻找到该块的开始,读取整个块,如果不使用该块,则将其丢弃。要写入块的一部分,必须寻找到块的开始,将整个块读入内存,修改数据,再次寻找到块的开头处,然后将整个块写回设备。

另一类 I/O 设备是字符特殊文件。字符设备以字符为单位发送或接收一个字符流,而不考虑任何块结构。字符设备是不可寻址的,也没有任何寻道操作。常见的字符设备有 打印机、网络设备、鼠标、以及大多数与磁盘不同的设备

每个设备特殊文件都会和 设备驱动 相关联。每个驱动程序都通过一个 主设备号 来标识。如果一个驱动支持多个设备的话,此时会在主设备的后面新加一个 次设备号 来标识。主设备号和次设备号共同确定了唯一的驱动设备。

我们知道,在计算机系统中,CPU 并不直接和设备打交道,它们中间有一个叫作 设备控制器(Device Control Unit)的组件,例如硬盘有磁盘控制器、USB 有 USB 控制器、显示器有视频控制器等。这些控制器就像代理商一样,它们知道如何应对硬盘、鼠标、键盘、显示器的行为。

绝大多数字符特殊文件都不能随机访问,因为他们需要使用和块特殊文件不同的方式来控制。比如,你在键盘上输入了一些字符,但是你发现输错了一个,这时有一些人喜欢使用 backspace 来删除,有人喜欢用 del 来删除。为了中断正在运行的设备,一些系统使用 ctrl-u 来结束,但是现在一般使用 ctrl-c 来结束。

网络

I/O 的另外一个概念是网络, 也是由 UNIX 引入,网络中一个很关键的概念就是 套接字(socket)。套接字允许用户连接到网络,正如邮筒允许用户连接到邮政系统,套接字的示意图如下

套接字的位置如上图所示,套接字可以动态创建和销毁。成功创建一个套接字后,系统会返回一个文件描述符(file descriptor),在后面的创建链接、读数据、写数据、解除连接时都需要使用到这个文件描述符。每个套接字都支持一种特定类型的网络类型,在创建时指定。一般最常用的几种

  • 可靠的面向连接的字节流
  • 可靠的面向连接的数据包
  • 不可靠的数据包传输

可靠的面向连接的字节流会使用管道 在两台机器之间建立连接。能够保证字节从一台机器按照顺序到达另一台机器,系统能够保证所有字节都能到达。

除了数据包之间的分界之外,第二种类型和第一种类型是类似的。如果发送了 3 次写操作,那么使用第一种方式的接受者会直接接收到所有字节;第二种方式的接受者会分 3 次接受所有字节。除此之外,用户还可以使用第三种即不可靠的数据包来传输,使用这种传输方式的优点在于高性能,有的时候它比可靠性更加重要,比如在流媒体中,性能就尤其重要。

以上涉及两种形式的传输协议,即 TCPUDP,TCP 是 传输控制协议,它能够传输可靠的字节流。UDP用户数据报协议,它只能够传输不可靠的字节流。它们都属于 TCP/IP 协议簇中的协议,下面是网络协议分层

可以看到,TCP 、UDP 都位于网络层上,可见它们都把 IP 协议 即 互联网协议 作为基础。

一旦套接字在源计算机和目的计算机建立成功,那么两个计算机之间就可以建立一个链接。通信一方在本地套接字上使用 listen 系统调用,它就会创建一个缓冲区,然后阻塞直到数据到来。另一方使用 connect 系统调用,如果另一方接受 connect 系统调用后,则系统会在两个套接字之间建立连接。

socket 连接建立成功后就像是一个管道,一个进程可以使用本地套接字的文件描述符从中读写数据,当连接不再需要的时候使用 close 系统调用来关闭。

Linux I/O 系统调用

Linux 系统中的每个 I/O 设备都有一个特殊文件(special file)与之关联,什么是特殊文件呢?

在操作系统中,特殊文件是一种在文件系统中与硬件设备相关联的文件。特殊文件也被称为 设备文件(device file)。特殊文件的目的是将设备作为文件系统中的文件进行公开。特殊文件为硬件设备提供了借口,用于文件 I/O 的工具可以进行访问。因为设备有两种类型,同样特殊文件也有两种,即字符特殊文件和块特殊文件

对于大部分 I/O 操作来说,只用合适的文件就可以完成,并不需要特殊的系统调用。然后,有时需要一些设备专用的处理。在 POSIX 之前,大多数 UNIX 系统会有一个叫做 ioctl 的系统调用,它用于执行大量的系统调用。随着时间的发展,POSIX 对其进行了整理,把 ioctl 的功能划分为面向终端设备的独立功能调用,现在已经变成独立的系统调用了。

下面是几个管理终端的系统调用

Linux IO 实现

Linux 中的 IO 是通过一系列设备驱动实现的,每个设备类型对应一个设备驱动。设备驱动为操作系统和硬件分别预留接口,通过设备驱动来屏蔽操作系统和硬件的差异。

当用户访问一个特殊的文件时,由文件系统提供此特殊文件的主设备号和次设备号,并判断它是一个块特殊文件还是字符特殊文件。主设备号用于标识字符设备还是块设备,次设备号用于参数传递。

每个驱动程序 都有两部分:这两部分都是属于 Linux 内核,也都运行在内核态下。上半部分运行在调用者上下文并且与 Linux 其他部分交互。下半部分运行在内核上下文并且与设备进行交互。驱动程序可以调用内存分配、定时器管理、DMA 控制等内核过程。可被调用的内核功能都位于 驱动程序 - 内核接口 的文档中。

I/O 实现指的就是对字符设备和块设备的实现

块设备实现

系统中处理块特殊文件 I/O 部分的目标是为了使传输次数尽可能的小。为了实现这个目标,Linux 系统在磁盘驱动程序和文件系统之间设置了一个 高速缓存(cache) ,如下图所示

在 Linux 内核 2.2 之前,Linux 系统维护着两个缓存:页面缓存(page cache)缓冲区缓存(buffer cache),因此,存储在一个磁盘块中的文件可能会在两个缓存中。2.2 版本以后 Linux 内核只有一个统一的缓存一个 通用数据块层(generic block layer) 把这些融合在一起,实现了磁盘、数据块、缓冲区和数据页之间必要的转换。那么什么是通用数据块层?

通用数据块层是一个内核的组成部分,用于处理对系统中所有块设备的请求。通用数据块主要有以下几个功能

将数据缓冲区放在内存高位处,当 CPU 访问数据时,页面才会映射到内核线性地址中,并且此后取消映射

实现 零拷贝机制,磁盘数据可以直接放入用户模式的地址空间,而无需先复制到内核内存中

管理磁盘卷,会把不同块设备上的多个磁盘分区视为一个分区。

利用最新的磁盘控制器的高级功能,例如 DMA 等。

cache 是提升性能的利器,不管以什么样的目的需要一个数据块,都会先从 cache 中查找,如果找到直接返回,避免一次磁盘访问,能够极大的提升系统性能。

如果页面 cache 中没有这个块,操作系统就会把页面从磁盘中调入内存,然后读入 cache 进行缓存。

cache 除了支持读操作外,也支持写操作,一个程序要写回一个块,首先把它写到 cache 中,而不是直接写入到磁盘中,等到磁盘中缓存达到一定数量值时再被写入到 cache 中。

Linux 系统中使用 IO 调度器 来保证减少磁头的反复移动从而减少损失。I/O 调度器的作用是对块设备的读写操作进行排序,对读写请求进行合并。Linux 有许多调度器的变体,从而满足不同的工作需要。最基本的 Linux 调度器是基于传统的 Linux 电梯调度器(Linux elevator scheduler)。Linux 电梯调度器的主要工作流程就是按照磁盘扇区的地址排序并存储在一个双向链表 中。新的请求将会以链表的形式插入。这种方法可以有效的防止磁头重复移动。因为电梯调度器会容易产生饥饿现象。因此,Linux 在原基础上进行了修改,维护了两个链表,在 最后日期(deadline) 内维护了排序后的读写操作。默认的读操作耗时 0.5s,默认写操作耗时 5s。如果在最后期限内等待时间最长的链表没有获得服务,那么它将优先获得服务。

字符设备实现

和字符设备的交互是比较简单的。由于字符设备会产生并使用字符流、字节数据,因此对随机访问的支持意义不大。一个例外是使用 规则(line disciplines)。一个行规可以和终端设备相关联,使用 tty_struct 结构来表示,它表示与终端设备交换数据的解释器,当然这也属于内核的一部分。例如:行规可以对行进行编辑,映射回车为换行等一系列其他操作。

什么是行规则?

行规是某些类 UNIX 系统中的一层,终端子系统通常由三层组成:上层提供字符设备接口,下层硬件驱动程序与硬件或伪终端进行交互,中层规则用于实现终端设备共有的行为。

网络设备实现

网络设备的交互是不一样的,虽然 网络设备(network devices) 也会产生字符流,因为它们的异步(asynchronous) 特性是他们不易与其他字符设备在同一接口下集成。网络设备驱动程序会产生很多数据包,经由网络协议到达用户应用程序中。

Linux 中的模块

UNIX 设备驱动程序是被静态加载到内核中的。因此,只要系统启动后,设备驱动程序都会被加载到内存中。随着个人电脑 Linux 的出现,这种静态链接完成后会使用一段时间的模式被打破。相对于小型机上的 I/O 设备,PC 上可用的 I/O 设备有了数量级的增长。绝大多数用户没有能力去添加一个新的应用程序、更新设备驱动、重新连接内核,然后进行安装。

Linux 为了解决这个问题,引入了 可加载(loadable module) 机制。可加载是在系统运行时添加到内核中的代码块。

当一个模块被加载到内核时,会发生下面几件事情:第一,在加载的过程中,模块会被动态的重新部署。第二,系统会检查程序程序所需的资源是否可用。如果可用,则把这些资源标记为正在使用。第三步,设置所需的中断向量。第四,更新驱动转换表使其能够处理新的主设备类型。最后再来运行设备驱动程序。

在完成上述工作后,驱动程序就会安装完成,其他现代 UNIX 系统也支持可加载机制。

我自己肝了 六本 PDF,关注公众号 Java建设者 回复 cxuan 领取全部资料,很宝贵的资料,如下


相关推荐

以文本的方式绘制简单的SVG流程图——flowchart.js

介绍flowchart.js是在浏览器和终端中运行的流程图DSL和SVG渲染。节点和连接是分别定义的,因此可以重复使用节点,并可以快速更改连接。也可以在DSL中对节点和连接器样式进行细微的更改。Git...

全国首套构网型SVG在木垒投运

中新网新疆新闻1月5日电(翟文辉)12月29日,全国首套构网型SVG在新疆木垒华电220千伏四十个井子汇集站并网,本项目是新疆电网继阿克陶构网型储能后又一次构网型支撑项目示范。为全面响应国家“双碳”...

Popmotion – 小巧,灵活的 JS 运动引擎

Popmotion是一个只有12KB的JavaScript运动引擎,可以用来实现动画,物理效果和输入跟踪。原生的DOM支持:CSS,SVG,SVG路径和DOM属性的支持,开箱即用。Popmoti...

零基础教你学前端——43、初识SVG

解决网站图标问题的最佳方案——SVG!SVG是一种基于XML语法的图像格式,英文全称是:ScalableVectorGraphics,即可缩放矢量图,是W3C的一项建议。我们用手机拍摄...

2.3 文件格式全解:PSD/JPG/PNG/SVG/GIF

2.3文件格式全解:PSD/JPG/PNG/SVG/GIF一、文件格式的核心意义文件格式是数字图像的存储规则,决定了:-信息保留程度(图层/透明度/动画)-压缩方式与画质损失-跨平台兼容性-...

vite v6.3.2 发布!HMR 优化+CSS 增强+稳定性提升,前端开发再提速!

前言:Vite6.3.2来了!2025年4月18日,Vite团队正式发布了v6.3.2版本!虽然是一个小版本更新,但修复了多个关键问题,并带来了性能优化和稳定性提升,让开发体验更丝滑!如果你还...

一篇文章带你了解SVG 蒙版(Mask)

SVG蒙版功能可将蒙版应用于SVG形状。蒙版可确定SVG形状的哪些部分可见,以及具有什么透明度。运行效果可以将SVG蒙版视为剪切路径的更高级版本。一、简单的蒙版代码解析:本示例使用ID=mask1定义...

SVG实现的流程图绘制

一、项目简介使用SVG技术实现的流程图绘制二、实现功能流程图块生成、连线、拖拽产生相应的xml和xpdl导入导出json数据放大缩小功能保存操作(选择、自动插入、开始结束、普通活动、子活动、块活动、路...

解锁国内 404 页面:Next.js 设置指南和 33 个有趣 SVG 资源分享

前言当我们访问网站时,如果访问到不存在的路径时,会出现404错误。为了避免给访问者带来不良体验,设计网站时通常会在页面上展示“404页面不存在”的提示,并引导用户进行返回首页等操作。因此在建立网...

交互设计师做好动画后,提交给开发的文档有哪些?

谢邀!简单的说一下自己的看法。首先从制作动画开始。目前制作动画的方式主要有:Gif动画视频动画Web动画,而Web动画又包括:CSS动画、JS动画(Canvas动画、原生JS动画API)、SVG动画等...

Motion for Vue:为Vue量身定制的强大动画库

在前端开发中,动画效果是提升用户体验的重要手段。Vue生态系统中虽然有许多动画库,但真正能做到高性能、易用且功能丰富的并不多。今天,我们要介绍的是MotionforVue(motion-v),...

Web开发人员的福音!8个实用的SVG工具

SVG可缩放矢量图形(ScalableVectorGraphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。SVG是W3C在2000年8月制定的一种新的二维矢量图形格式...

一键画波浪线、一键多图片调色?这3个网站好玩到停不下来

作为一个经常收集网站的PPT设计师,无意中发现了一些超级有趣的网站。只要你动手能力足够强,就一定会利用它做出创意作品。不说废话,直接进入主题。1、炫酷的光线绘画网站http://weavesilk.c...

vite 6.2.5 更新速递:告别SVG路径Bug,构建效率再提升!

Vite6.2.5更新公告2025年4月3日,Vite团队正式发布了Vite6.2.5版本!此次更新虽然是一个小版本迭代,但修复了一个关键问题,涉及SVG文件路径检查,对前端开发者尤...

DrawSVG – SVG 路径动画 jQuery 插件

jQueryDrawSVG使用了jQuery内置的动画引擎实现SVG路径动画,用到了stroke-dasharray和stroke-dashoffset属性。DrawSVG是完全...