当前位置: 首页 > news >正文

线程如何从“跑代码”变成“让 OS 干活”?

主要关注这四件事:

  • 为什么必须区分用户态 / 内核态?

  • 什么是系统调用?它解决了什么?

  • 系统调用与中断的关系是什么?

  • 一次系统调用在 OS 中发生了什么?(最小流程)

为什么必须有用户态 / 内核态?

从 前面几篇已知事实出发:

  • 程序共享 CPU

  • 程序共享机器

  • 程序不可信(可能崩溃 / 恶意 / Bug)

如果程序能直接:

  • 访问物理内存

  • 修改页表

  • 操作硬件

  • 控制中断

  • 修改调度器

那结果只有一个:

任何程序都可以破坏整个系统。

因此 OS 必须做一件事:

把“能干危险事的代码”和“普通程序代码”强制隔离。


两个模式由硬件强制区分

  • 用户态(User Mode)

    • 不能访问硬件

    • 不能操作页表

    • 不能关中断

    • 不能调度线程

  • 内核态(Kernel Mode)

    • 可以操作一切

    • 控制内存、CPU、设备、调度

这不是 OS 约定,是 CPU 硬件级强制。


那程序怎么“让 OS 干活”?——系统调用

问题来了:

用户态程序既然不能直接干危险事,
那它怎么读文件、发网络、创建线程?

答案只有一个:

系统调用(System Call)

系统调用的本质是:

用户态程序请求内核态代码代为执行受保护操作。

关键点:

  • 程序不能自己切到内核态

  • 只能通过CPU 提供的受控入口

  • 内核决定允不允许、怎么做、做多久


系统调用解决了什么?

  1. 安全:程序不能越权

  2. 隔离:只能操作自己的资源

  3. 统一管理:OS 统一调度 I/O、内存、线程

系统调用是用户态 → 内核态的唯一合法通道

系统调用 vs 中断

这是 这篇文章的 的关键区分点。


系统调用(System Call)

  • 谁触发?用户程序

  • 是否主动?

  • 目的?请求 OS 服务

  • 例子?read / write / fork / mmap


中断(Interrupt)

  • 谁触发?硬件

  • 是否主动?

  • 目的?通知 OS 事件发生

  • 例子?

    • 磁盘 I/O 完成

    • 网络包到达

    • 定时器中断(时间片)

核心一句话:

系统调用是“我想要”;中断是“事情发生了”。

一次系统调用的最小执行流程

不讲细节,只讲不可省略的骨架

read()为例:

[用户态]
程序调用 read(fd, buf, size)

CPU 执行 syscall / trap 指令

CPU 切换到内核态

进入内核的系统调用处理函数

内核检查参数 / 权限

如果数据未就绪 → 线程进入 Blocked

调度器切换到其他线程

(某个时刻)I/O 完成 → 硬件中断

内核处理中断,唤醒线程

线程回到 Ready → Running

系统调用返回

CPU 切回用户态

系统调用、阻塞、调度、中断
在这一条路径里全部串起来了。
这是五篇文章的完整闭环。

Day5 的三条不可混淆结论

① 用户态 / 内核态是硬件强制隔离,不是软件约定。

② 系统调用是用户态进入内核态的唯一合法方式。

③ 中断是硬件通知 OS 的机制,与系统调用完全不同。

接下来是对应的问题:

Q1:为什么必须区分用户态和内核态?(一句话)

Q2:系统调用的本质是什么?(一句话)

Q3:系统调用和中断的区别是什么?(一句话)

Q4:为什么用户态不能直接操作硬件或内存?(一句话)

Q5:一次 read() 可能为什么会阻塞?阻塞期间 CPU 在干什么?

回答完之后,OS主线就基本串联完成了。

标准答案:

Q1:为了防止用户程序直接操作硬件、内存和内核数据,从而破坏整个系统。

关键词必须包含:用户程序 / 硬件或内核 / 破坏系统

Q2:系统调用是用户态程序通过受控入口请求内核代为执行受保护操作。

Q3:系统调用是用户程序主动请求内核服务;中断是硬件被动通知内核事件发生。

Q4:因为用户态程序不可信,若能直接操作硬件或内存会破坏系统隔离与安全。

Q5:read 会因等待 I/O 数据而阻塞;阻塞期间线程进入 Blocked,CPU 被调度去执行其他线程。

原理解(用于自己复盘纠正):

Q1,为了系统安全(只有结果,没有因果,不够)
Q2,程序对系统内核申请权限并返回数据

“申请权限”这个说法不准确
系统调用不是动态申请权限,而是受控进入内核执行受保护操作

Q3,系统调用是用户态与内核态之间的机制,而中断是硬件层面和os的机制

不够精确,缺“主动 / 被动”这条关键分界线。

系统调用是用户程序主动请求内核服务;中断是硬件被动通知内核事件发生。

Q4,因为不安全

过于抽象,说完整一点= =

因为用户态程序不可信,若能直接操作硬件或内存会破坏系统隔离与安全。

Q5,read在等待os返回所需数据,阻塞期间cpu在请求系统内核的数据

直接把“线程在做什么”和“CPU在做什么”混到了一句话里。

即半对半错:

“这个 read 的请求已经交给内核 / 设备了,系统在处理 I/O”

这一点是对的,但——
处理 I/O 的不是 CPU 在“等着跑”

Q5 拆分成三层来理解:

1.线程在干什么?(Thread 视角)

线程调用 read()
→ 发现数据还没准备好
→ 被内核挂起
→ 状态变为 Blocked
→ 不再参与 CPU 调度

没后续了

2.那CPU在干嘛?(CPU / Scheduler 视角)

CPU 发现当前线程 Blocked
→ 立即进行一次调度
→ 切换上下文
→ 去执行其他 Ready 线程

CPU 从来不会“等 I/O 数据”。

CPU 只做两件事:

  • 执行指令

  • 切换执行对象

3.谁在跑I/O?(设备 / 中断视角)

磁盘 / 网卡 / DMA / 控制器
→ 在硬件层面异步处理 I/O
→ 完成后触发中断
→ 通知内核

I/O 处理是“设备在干活”,不是 CPU 在干活。

Q5修改后的答案:read 发起 I/O 请求后,线程被阻塞,CPU 去执行其他线程,I/O 由设备异步完成,完成后通过中断唤醒线程。

必须纠正:“阻塞”描述的是线程状态,不是 CPU 行为。

http://www.jsqmd.com/news/95310/

相关文章:

  • Dify平台创建音乐智能体:输入歌词即可由ACE-Step谱曲
  • 使用Ollama运行Seed-Coder-8B-Base:本地部署大模型的新选择
  • DamaiHelper:告别手动抢票,轻松获取演唱会门票
  • Vue-next-admin:5大核心功能助你快速搭建专业后台管理系统
  • git——从stash list里取文件
  • Diablo Edit2完全指南:从零开始掌握暗黑破坏神II角色编辑的5大核心技巧
  • 【技术干货】常规ML推理vs LLM推理:5大核心差异与解决方案详解(建议收藏)
  • Blender 贝塞尔曲线终极操作指南:全面掌握曲线编辑技巧
  • 3个技巧告别论文格式困扰:XMU-thesis让学术写作更高效
  • 5步搭建终极开源告警管理中心:Keep平台完整实战指南
  • Linux下安装使用Claude遇到的问题及解决方案
  • Python脚本批量生成Qwen-Image输入Prompt模板
  • Ollama下载模型时报错?检查Qwen3-VL-8B路径权限
  • 基于springboot的美食推荐商城的设计与实现
  • 企业级微服务权限系统终极指南:RuoYi-Cloud-Plus完整解析
  • 本地运行大模型不再是梦:Seed-Coder-8B-Base + Ollama实战指南
  • RAG优化思路
  • 使用HuggingFace镜像网站快速拉取Qwen-Image-Edit-2509模型
  • GitHub最新Stable-Diffusion-3.5-FP8镜像发布!一键部署生成高质量图像
  • 【C++】用哈希表封装unordered_map和unordered_set
  • HunyuanVideo-Foley GitHub镜像加速下载方法(支持国内网络)
  • 【收藏】AI真相:别再盲目学习AI工具了,真正难被取代的是这种能力
  • Flutter + OpenHarmony 性能优化全链路指南:从启动加速到帧率稳定,打造丝滑鸿蒙体验
  • SQLite Studio:重新定义数据库探索体验的现代化工具
  • DesktopNaotu桌面脑图工具终极使用指南
  • 回溯
  • 开源2026 H5棋牌游戏采用 Cocos Creator开发 支持PC+移动设备
  • 9款AI写论文哪个好?实测后我发现:只有它敢把图表数据和参考文献“亮出来给你查
  • IGBT驱动设计要点(一)懵逼版
  • 【建议收藏】PEFT与LoRA全解析:大模型参数高效微调技术,降低95%显存需求