news 2026/5/26 8:27:47

线程如何从“跑代码”变成“让 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/5/26 3:21:10

英伟达Scale-out网络为何兼有IB和以太网?——算力芯片看点系列

内容要点: ◼ IB与Ethernet之争,性能与通用性的博弈。 InfiniBand(IB)和以太网(Ethernet)是两种常见而又不同的网络技术。二者对比来看,IB在带宽、延迟、可靠性方面的表现更为出色,适…

作者头像 李华
网站建设 2026/5/25 12:41:11

从功能测试到测试开发:我的技术转型之路

职业定位的升级:从质量验证到质量共建 在传统的软件测试岗位上,我们往往扮演着"质量守门员"的角色,主要工作集中在产品开发后期进行缺陷排查。然而,随着敏捷开发和DevOps理念的普及,测试工作正在发生根本性…

作者头像 李华
网站建设 2026/5/26 3:39:02

Blender 贝塞尔曲线终极操作指南:全面掌握曲线编辑技巧

Blender 贝塞尔曲线终极操作指南:全面掌握曲线编辑技巧 【免费下载链接】blenderbezierutils 项目地址: https://gitcode.com/gh_mirrors/bl/blenderbezierutils 想要在 Blender 中轻松驾驭贝塞尔曲线吗?这款强大的插件将彻底改变你的工作流程&a…

作者头像 李华
网站建设 2026/5/26 4:17:22

大数据架构演进:数据网格(Data Mesh)核心概念解析

大数据架构演进:数据网格(Data Mesh)核心概念解析 关键词:大数据架构、数据网格(Data Mesh)、领域自治、数据产品、自助服务、全局治理、架构演进 摘要:本文从传统大数据架构的痛点出发,结合生活场景类比,系统解析数据…

作者头像 李华
网站建设 2026/5/26 4:19:47

如何在16GB内存设备上部署GPT-OSS-20B?清华源镜像加速下载实战

如何在16GB内存设备上部署GPT-OSS-20B?清华源镜像加速下载实战 你有没有遇到过这样的场景:想本地跑一个大模型做实验,结果光是下载权重就卡了整整一夜,最后还断了线?更别提加载时显存爆满、系统卡死的尴尬。这几乎是每…

作者头像 李华
网站建设 2026/5/25 23:51:52

函数的练习

编写一个主函数以及四个函数max(a, n)、min(a, n)、aver(a, n)和prime(m)。要求是:函数max(a, n)、min(a, n)和aver(a, n)分别求出含有n个元素的数组a中的最大值、最小值和平均值,并返回结果到主调函数。函数prime(m)要求对m是否为素数进行判断&#xff…

作者头像 李华