news 2026/3/13 13:51:59

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
线程如何从“跑代码”变成“让 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 行为。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/12 22:18:15

30分钟搭建 Typecho 个人博客教程

Typecho 是一款 PHP 博客程序,相比于 WordPress,Typecho 显得更加的轻量级和简洁。现在越来越多的人倾向于用 Typecho 来搭建个人博客——众所周知,能跑 WordPress 的机器都不便宜。 Typecho 是一款国人团结打造的开源博客系统,和…

作者头像 李华
网站建设 2026/3/5 3:25:17

微软拼音卡顿

适用于输入没有反应将尝试必应的文本建议关闭

作者头像 李华
网站建设 2026/3/12 7:54:40

基于springboot的美食推荐商城的设计与实现

系统介绍 本文介绍了一个基于Java开发的B/S架构美食管理系统,系统实现了用户在线答题和分数查询功能,管理员可管理购物车、公告、美食订单等10个核心模块。开发环境采用SpringBoot框架,MySQL数据库,支持IDEA/Eclipse工具。系统包…

作者头像 李华
网站建设 2026/3/5 3:01:37

告别焦虑!网络工程师AI进化全攻略,建议永久收藏

文章指出AI不会取代网络工程师,但会取代不学习AI的网络工程师。网络工程师需从"命令行"操作转向"智能协作者",通过三个阶段学习路线掌握AI技能,重点培养学习能力、思辨能力、沟通协作和创新思维。强调人机协作是未来趋势…

作者头像 李华