
大家好,欢迎来到 huangjin007_ 的博客
⭐
个人主页:huangjin007_
🔥
文章收录专栏:Linux 内功修炼手册(系统篇)
总会有一些坚持能从冰封的土地里培育出十万朵怒放的蔷薇
Linux 系统篇(十三) —— 冯诺依曼体系结构、操作系统
文章目录
- Linux 系统篇(十三) —— 冯诺依曼体系结构、操作系统
-
- 一、冯·诺依曼体系结构
-
- 1.1 五大核心部件
- 1.2 至关重要的“数据流动”
- 1.3 为什么程序必须先加载到内存?
- 1.4 性能瓶颈的本质:速度差异
- 1.5 计算机存储金字塔
- 1.6 用实际场景理解数据流动:QQ 聊天与文件传输
- 二、操作系统
-
- 2.1 操作系统的定义与组成
- 2.2 设计操作系统的目的
- 2.3 操作系统的核心定位:“搞管理”的软件
- 2.4 深入理解“管理”:以校长、辅导员和学生为例
- 2.5 系统调用
- 2.6 库函数
- 结语:
一、冯·诺依曼体系结构
今天绝大多数的计算机——无论是你桌上的笔记本,还是云端的服务器——都遵循着同一个经典设计,那就是冯·诺依曼体系结构。

1.1 五大核心部件
冯·诺依曼体系把计算机划分成五个功能明确的组件:
- 输入设备:负责把外界的信息输入给计算机。例如键盘、鼠标、扫描仪、麦克风,甚至网卡在接收数据时也扮演输入设备的角色。
- 输出设备:负责把计算机处理完的结果输出给外界。例如显示器、打印机、音箱,以及向外发送数据时的网卡。
- 存储器:这里特指 内存,也叫主存。它是一个临时存放数据和指令的地方,特点是读写速度快,但断电后数据会丢失。
- 运算器:专门负责算术运算和逻辑运算。
- 控制器:是整个计算机的指挥中心,负责解析指令,协调各个部件有序工作。
通常,运算器和控制器被集成在一块芯片上,也就是我们熟知的 CPU(中央处理器)。
1.2 至关重要的“数据流动”
- CPU 只能直接和内存打交道(数据层面)。CPU 要读取指令或数据,必须从内存里拿;CPU 算完的结果,也必须先写回内存。它不能绕过内存直接去读写硬盘、键盘、网卡这些外设。
- 外设也只能和内存打交道。你想让键盘输入被程序收到,必须是键盘先把数据写入内存的某个区域,然后 CPU 再从那里读走。同样,CPU 想显示点东西在屏幕上,得先把数据写到内存里某处,再由显示器从内存中取走显示。
换句话说:内存是所有硬件数据交换的中转站。所有的数据流,都要经过内存这个十字路口。
1.3 为什么程序必须先加载到内存?
我们平时的软件、可执行程序,本质都是存放在硬盘上的静态文件。 但有一个冯·诺依曼体系的硬性规则:CPU 只能直接读取内存中的指令和数据,无法直接访问硬盘等外设。
因此程序无法直接在硬盘上运行。当我们双击打开程序时,操作系统会自动把硬盘上的可执行文件,搬运加载到内存中,完成指令与数据的布局。只有进入内存后,CPU 才能逐条取指令、解析、执行,程序才能真正跑起来。
1.4 性能瓶颈的本质:速度差异
计算机整体性能遵循木桶效应,最大瓶颈来自各级硬件的速度严重不匹配。
硬件速度层级差距极大(从快到慢):
CPU(纳秒级) > 内存(微秒级) > 硬盘/网络(毫秒级)
CPU 运算速度极快,但硬盘、网络等外设速度极其缓慢。 如果 CPU 直接读写硬盘,绝大部分时间都会在空等数据,资源彻底浪费。
而内存速度远高于磁盘,作为高速中间中转站,专门用来衔接超快的 CPU 和超慢的外设。先把数据提前加载到内存,CPU 全速从内存读取执行,避免低效等待。
所以计算机最大的性能瓶颈本质:不是 CPU 算得不够快,而是低速设备的数据搬运速度跟不上 CPU 的运算速度。
为缓解这种速度矛盾,现代计算机在 CPU 与内存之间增设多级高速缓存,构建起一套存储金字塔:越靠近 CPU 的存储介质,速度越快、容量越小、单位成本越高;越底层的存储,速度越慢、容量越大、价格更低,以此兼顾性能与硬件成本。
1.5 计算机存储金字塔

- L0:CPU寄存器 位于CPU芯片内部,与运算器、控制器同频工作,是整个计算机速度最快的存储。容量极小,单位是字节,专门存放CPU当下正在运算的数据、地址,直接供CPU执行指令使用。
- L1 / L2 高速缓存(SRAM) 集成在CPU芯片内部,离CPU核心极近,读写速度极快。容量一般几十KB ~ 几百KB。 L1缓存为每个CPU核心独占;L2缓存容量更大、速度略慢,同样绑定单个核心。
- L3 高速缓存(SRAM) 速度弱于L1、L2,但容量大幅提升,一般几MB ~ 几十MB。由CPU所有核心共享,多核之间可以借助L3交换数据。
- L4:主存(DRAM,也就是我们常说的内存) 程序运行的主战场,容量GB级别。相比缓存,访问速度下降明显。断电数据全部丢失,只负责存放当前正在运行的程序与数据。
- L5:本地二级存储(磁盘、SSD、U盘) 就是电脑硬盘,TB级超大容量。速度远低于内存,断电数据永久保存。我们的软件、文档、文件全部存放在这里。只有程序被启动时,数据才会加载到主存。
- L6:远程二级存储 分布式文件系统、云服务器、Web服务器等网络远端存储。数据存放在互联网远端服务器,通过网络读取,容量几乎没有上限,但受网速限制访问最慢。
规律总结:越靠近 CPU,速度越快、容量越小、成本越高;越往下,容量越大、成本越低、但速度也越慢。
1.6 用实际场景理解数据流动:QQ 聊天与文件传输
光背概念不够,我们得把数据流动的过程走一遍,才能真正理解冯·诺依曼体系是如何贯穿在每一次操作里的。

场景一:你在 QQ 上给朋友发一条文字消息
你(北京用户)在键盘上敲字,点击发送。这一刻发生了什么?
场景二:南京朋友收到你的消息
场景三:在 QQ 上发送一个文件
发送文件的流程和发消息整体相似,只是数据量大得多,且在发送端和接收端会涉及硬盘读写:
- 发送端(北京):硬盘(外存)上的文件 → 内存 → 网卡(输出设备) → 互联网。
- 接收端(南京):网卡(输入设备) → 内存 → 硬盘(外存),文件最终被保存到对方的磁盘里。
二、操作系统
了解了硬件的运作规律之后,新的问题出现了:谁负责把程序从硬盘搬到内存?谁来协调多个程序同时使用 CPU?这就引出了操作系统。
2.1 操作系统的定义与组成
任何一台完整的计算机系统里,都包含一套最基本的程序集合,它叫做操作系统(Operating System,OS)。它可以粗略分成两大块:
- 内核(Kernel):操作系统的核心,直接掌管硬件,负责进程管理、内存管理、文件系统、设备驱动、网络协议栈等关键模块。内核工作在最高特权级,可以执行任何指令。
- 外壳程序与工具集:比如命令行解释器(shell)、图形界面、各种基础函数库等。它们不是内核,但为用户和程序员提供了与内核交互的便捷途径。

我们常用的 Linux、Windows、macOS,最本质的区别就体现在内核的设计与实现上。
2.2 设计操作系统的目的
操作系统被设计出来,肩负着两个方向的任务:
- 向下(对硬件):充当硬件的直接管理者。它要能够识别和控制各种乱七八糟的硬件设备,向上层隐藏硬件操作的复杂性。比如磁盘读写的细节、网卡驱动协议等,应用软件完全不用关心。
- 向上(对应用程序):为用户程序提供一个良好的、安全的执行环境。多个程序要能同时运行并且互不干扰,程序要能方便地申请内存、读写文件、访问网络,并且不能因为某个程序出错而导致整个系统崩溃。

2.3 操作系统的核心定位:“搞管理”的软件
在整个计算机架构中,操作系统是一款纯粹的“搞管理”的软件。那么,“管理”这个词具体该怎么理解呢?我们用一个生活中的例子来类比。
2.4 深入理解“管理”:以校长、辅导员和学生为例
假设一所大学有几万名学生,校长不可能认识每一个人,他怎么能管理好整个学校呢?
把这个逻辑平移到操作系统对计算机硬件的管理上:
- 描述硬件:操作系统会为每一个硬件设备,甚至每一个运行的程序,都创建一个对应的结构体,里面记录着它所有的状态和属性。
- 组织硬件/软件:比如所有的进程,操作系统会把它们描述成进程控制块(PCB,Process Control Block),在 Linux 里就是那个著名的 task_struct 结构体。然后把所有进程的 PCB 按照状态(比如就绪、阻塞)放入不同的队列中进行组织。(这些后面的文章中会做详细讲解)
- 实施管理:当操作系统要调度 CPU 执行哪个程序时,它只需要去“就绪队列”里查看排队的 PCB,根据一定的规则挑出一个,然后切换到那个进程运行即可。
所以,操作系统的管理哲学可以浓缩为八个字:先描述,再组织。 描述了,才能统一管理;组织起来了,才能高效检索和调度。这个思想贯穿了进程管理、内存管理、文件管理、设备管理等所有 OS 子模块。在后面我们深入进程管理的时候,你会发现,整个 Linux 进程体系的秘密,就藏在对 task_struct 的描述和各种运行队列的组织里。
2.5 系统调用
现在我们知道,操作系统内核拥有最高权限,可以操作所有硬件。但普通的应用程序(比如浏览器、游戏)运行在用户空间,权限受到严格限制。如果它们想读写文件、申请内存、发送网络数据,该怎么办?直接操作硬件肯定不行,会引发灾难。
于是,操作系统对外暴露了一套经过精心设计的接口,应用程序可以用这些接口来“申请服务”,这套接口就叫做系统调用(System Call)。
- 类比理解:你去银行存钱,自己不能走进金库把钱放进去(不能直接操作硬件)。你必须到柜台窗口,把存折和现金交给柜员(发起系统调用)。柜员(内核)在内部完成核验、记账、入库等一系列操作,最后把存折还给你。这里的“柜台窗口”就是系统调用接口,柜员就是操作系统内核。
- 具体例子:在 C 语言里写 printf("hello world\\n");,表面上调用了一个库函数,但它的底层必然要调用操作系统提供的 write 系统调用,请求内核把字符串写到标准输出(通常是显示器)。内核接到请求后,验证权限,找到显示器的驱动程序,最终在屏幕上呈现出这几个字符。
系统调用是内核提供的“服务”。例如,Linux 里 open()、read()、write()、fork() 等都是系统调用。
2.6 库函数
正因系统调用过于底层,开发者们开始对它进行封装,形成更易用的函数库。有了库,上层开发就方便多了。
- 标准 C 库(libc) 就是一个绝佳的范例:printf 内部封装了 write,替你处理了格式化字符串、缓冲等细节;malloc 封装了 brk 或 mmap 等内存相关的系统调用,让你可以轻松申请动态内存。
- 其他高级语言的运行时、图形界面框架等,也都是一层层建立在系统调用之上的封装。
因此,现代软件的层次关系可以简化为:
应用程序 → 库函数 → 系统调用 → 操作系统内核 → 硬件
每一层都屏蔽了下层的复杂性,为上层提供更友好的服务。
结语:
今天的内容到这里就结束了,希望你能有所收获~
干货整理到手抖,觉得有用的话,赏个三连回回血?__(:ᗤ」ㄥ)_ _
网硕互联帮助中心






评论前必须登录!
注册