【Linux】 存储分级的秘密

前言:欢迎 各位光临本博客,这里小编带你直接手撕**,文章并不复杂,愿诸君**耐其心性,忘却杂尘,道有所长!!!!

IF'Maxue个人主页
🔥 个人专栏 :
《C语言》
《C++深度学习》
《Linux》
《数据结构》
《数学建模》

⛺️生活是默默的坚持,毅力是永久的享受。不破不立!

文章目录

  • [1. 软件为啥非要先"搬"到内存?------存储分级的秘密](#1. 软件为啥非要先“搬”到内存?——存储分级的秘密)
  • [2. 两台电脑传文件:本质是"冯诺依曼"之间的快递](#2. 两台电脑传文件:本质是“冯诺依曼”之间的快递)
  • [3. 操作系统:电脑的"小区物业"](#3. 操作系统:电脑的“小区物业”)
  • [4. 操作系统怎么管东西?------先描述,再组织](#4. 操作系统怎么管东西?——先描述,再组织)
  • [5. 系统调用:你和硬件之间的"银行柜台"](#5. 系统调用:你和硬件之间的“银行柜台”)
  • [6. 进程管理:OS怎么"盯"着程序跑?](#6. 进程管理:OS怎么“盯”着程序跑?)

1. 软件为啥非要先"搬"到内存?------存储分级的秘密

咱们平时用软件(比如打开Excel),没运行时,它的代码和数据都躺在磁盘里------就像东西存放在家里的仓库。但一运行,这些东西必须先拷贝到内存,为啥?

因为电脑里的"干活的"(运算器、键盘这些硬件)都很"傲娇":只跟内存打交道。这不是它们耍大牌,是计算机体系结构规定的------就像公司规定"报销只能找财务,不能直接找老板"。

背后更核心的原因是"存储分级",简单说就是"越快的越小越贵,越慢的越大越便宜",就像下图展示的:

  • 最快的是CPU缓存:相当于你口袋里的零钱,拿起来最快,但装不了多少;
  • 中间的是内存:像家门口的快递柜,比口袋能装,拿取速度也快;
  • 最慢的是磁盘:就是家里的大仓库,能放很多东西,但找东西要半天。

而且软件跑多快,不看最快的CPU,只看最慢的环节(比如磁盘)------就像快递配送,飞机再快,最后一公里送得慢,整体还是慢。所以得先把磁盘里的程序"搬"到内存,让运算器能快速拿到数据,不耽误干活。

2. 两台电脑传文件:本质是"冯诺依曼"之间的快递

你给朋友传个照片,看似点一下"发送"就完了,其实背后是一套"快递流程",而且本质是两台冯诺依曼体系电脑在交流(冯诺依曼体系就是电脑按"先存程序,再跑程序"的逻辑工作)。

具体流程就像这样:

你电脑的磁盘(你家仓库)→ 你电脑的内存(你家客厅)→ 你电脑的网卡(快递员)→ 网络(马路)→ 朋友电脑的网卡(朋友家快递员)→ 朋友电脑的内存(朋友家客厅)→ 朋友电脑的磁盘(朋友家仓库)。

一句话总结:文件先"搬"到内存,再交给"快递员",送到对方后,先放内存,最后存仓库------这就是两台冯诺依曼电脑交流的核心逻辑。

3. 操作系统:电脑的"小区物业"

你用微信、玩游戏时,从不用管"键盘怎么识别输入""内存够不够用"------这都是操作系统(OS) 在帮忙。它就像小区物业:

  • 硬件(键盘、内存、磁盘)是小区里的电梯、水管(基础设施);
  • 软件(微信、游戏)是小区业主;
  • 物业(OS)的作用:帮业主协调用电梯(比如你打字时,OS让键盘把数据传给微信),不用业主自己去修电梯、管水管。

操作系统分两部分,就像下图里展示的结构:

  • 内核 :物业的"核心部门",管最关键的事:
    • 进程管理:安排业主的"活动"(比如让微信和浏览器轮流用CPU);
    • 内存管理:分配小区"车位"(给每个程序分内存空间);
    • 文件管理:管业主的"快递"(比如你存的照片、文档);
    • 驱动管理:找"电梯维修师傅"(让硬件能正常工作,比如显卡驱动)。
  • 其他程序 :物业的"前台和服务",比如:
    • Shell(命令行):物业前台,你输ls"查快递",前台就告诉内核去查文件;
    • 函数库:比如C语言的printf,像物业的"便民服务",帮你简化操作。

4. 操作系统怎么管东西?------先描述,再组织

不管是管进程、管文件,OS的核心逻辑就一句话:先描述,再组织 。用学校管理的例子(像下图里的思路),一看就懂:

比如校长要管1000个学生,第一步不是直接喊名字,而是"先描述":

给每个学生建一张"信息卡",记着姓名、学号、班级------就像OS管进程时,先给每个进程建一张"信息卡"(后面会说的task_struct),记着进程ID、状态、占用内存。

然后"再组织":把这些"信息卡"按班级串起来(比如用链表,像串珠子)------OS就用链表、数组这些结构,把进程的"信息卡"组织起来。

这样校长要找"张三",不用挨个教室问,直接查链表;OS要找某个进程,也不用遍历所有程序,直接查组织好的结构。

这里用C语言写个简单例子,帮你理解"描述+组织":

c 复制代码
// 1. 先"描述":用结构体存每个学生的信息(相当于"信息卡")
struct Student {
    char name[20];  // 姓名
    int id;         // 学号
    char class[10]; // 班级
    struct Student* next; // 指向下一个学生,用来"组织"
};

// 2. 再"组织":用链表把学生串起来(相当于"按班级串信息卡")
struct Student* student_list = NULL; // 链表头(第一个学生)

// 新增学生 = 链表加节点(校长"收新学生")
void add_student(char* name, int id, char* class) {
    struct Student* new_stu = malloc(sizeof(struct Student));
    strcpy(new_stu->name, name);
    new_stu->id = id;
    strcpy(new_stu->class, class);
    new_stu->next = student_list; // 插在链表头
    student_list = new_stu;
}

// 查学生 = 遍历链表(校长"找学生")
struct Student* find_student(int id) {
    struct Student* p = student_list;
    while (p != NULL) {
        if (p->id == id) return p;
        p = p->next;
    }
    return NULL;
}

其实世界上所有管理,都是先描述再组织:比如公司管员工(先记工号、部门,再按部门分组),超市管商品(先记条码、价格,再按货架分类)------OS也不例外。

5. 系统调用:你和硬件之间的"银行柜台"

OS有个矛盾:既不相信你(怕你乱改硬件,比如删了系统文件),又得帮你干活(比如你要读磁盘里的照片)。怎么解决?------开"柜台",也就是系统调用

这就像银行:你要取金库的钱(访问硬件),不能自己进金库(直接操作磁盘),得去柜台(调用系统调用),银行职员(OS)帮你取。

  • 本质 :OS提供的C语言函数接口,比如你要读文件,就调用open();要写数据,就调用write()
  • 关键规则:你写的程序想碰硬件,必须通过系统调用让OS帮忙------没有例外。

还有个容易搞混的点:库函数和系统调用的关系 。比如你常用的printf("Hello")(库函数),看起来简单,底层其实调用了write()系统调用(让文字显示在屏幕上)。

简单说:库函数是"银行APP",系统调用是"银行柜台"。你用APP转账(用库函数),比直接去柜台(写系统调用)方便,但APP最终还是会调用柜台接口。

用代码举个例子,看底层关系:

c 复制代码
#include <stdio.h>
int main() {
    // 库函数:用起来简单,不用管底层怎么跟硬件交互
    printf("Hello World!\n"); 
    return 0;
}

// 编译后看底层:用gcc -S test.c生成汇编代码,会发现printf最终调用了write系统调用
// 结论:只要库函数要碰硬件(比如打印到屏幕),底层一定藏着系统调用

6. 进程管理:OS怎么"盯"着程序跑?

你打开的微信、浏览器,在OS里都叫"进程"------OS管进程,其实是管一个叫task_struct的东西(也叫PCB,进程控制块)。

task_struct就是进程的"身份证+说明书",像下图里展示的,里面记着进程的所有关键信息:

  • 进程ID(PID):相当于身份证号,唯一标识一个进程;
  • 进程状态:是"正在运行""等着CPU"还是"睡着了";
  • 占用资源:用了多少内存、CPU跑了多久;
  • 打开的文件:比如进程打开的文档、图片。


OS管理进程,其实就是管理这些task_struct------比如把它们用链表组织起来,要启动进程就加个节点,要停进程就删节点。

最后说几个常用的Linux命令,帮你实际操作进程(效果像下图里展示的):

bash 复制代码
# 1. 查看所有进程:像OS查所有"正在活动的程序"
ps axj

# 2. 找特定进程:比如找"firefox"(浏览器)的进程
ps axj | grep firefox

# 3. 杀掉进程:比如杀掉PID为1234的进程(PID从ps命令里看)
kill 1234

# 4. 更改进程的当前路径:比如让进程的"当前工作目录"改成/home
cd /home  # Shell命令,底层调用chdir()系统调用

如果想通过代码改进程路径,也很简单,就像下图示例的逻辑:

c 复制代码
#include <unistd.h>
#include <stdio.h>
int main() {
    // 系统调用:直接改当前进程的路径
    int ret = chdir("/home");
    if (ret == 0) {
        printf("进程当前路径已改成 /home\n");
    }
    return 0;
}

简单说:你用命令或代码操作进程,其实是告诉OS"去改task_struct的信息"------比如kill命令,就是让OS把某个task_struct标记为"终止",然后回收资源。

相关推荐
不做菜鸟的网工2 小时前
Headscale 的部署方法和使用教程
运维
天天进步20152 小时前
掌握React状态管理:Redux Toolkit vs Zustand vs Context API
linux·运维·react.js
艾醒(AiXing-w)2 小时前
探索大语言模型(LLM):Ollama快速安装部署及使用(含Linux环境下离线安装)
linux·人工智能·语言模型
垚垚领先2 小时前
Kdump 文档 - 基于 kexec 的崩溃转储解决方案
linux
tongsound2 小时前
igh ethercat 实时性测试
linux·c++
大翻哥哥2 小时前
Python 2025:低代码开发与自动化运维的新纪元
运维·python·低代码
柯南二号3 小时前
【Java后端】Spring Boot 集成雪花算法唯一 ID
java·linux·服务器
半梦半醒*3 小时前
正则表达式
linux·运维·开发语言·正则表达式·centos·运维开发
海域云SeaArea_3 小时前
CentOS7 安装 Jumpserver 3.10.15
运维