CPU 空闲时会干吗?

人空闲时会发呆会无聊,计算机呢?

假设你正在用计算机浏览网页,当网页加载完成后你开始阅读,此时你没有移动鼠标,没有敲击键盘,也没有网络通信,那么你的计算机此时在干嘛?

有的同学可能会觉得这个问题很简单,但实际上,这个问题涉及从硬件到软件、从 CPU 到操作系统等一系列环节,理解了这个问题你就能明白操作系统是如何工作的了。

你的计算机 CPU 使用率是多少?

如果此时你正在计算机旁,并且安装有 Windows 或者 Linux ,你可以立刻看到自己的计算机 CPU 使用率是多少。

这是博主的一台安装有 Win10 的笔记本:

可以看到大部分情况下 CPU 利用率很低,也就在 8% 左右,而且开启了 283 个进程,这么多进程基本上无所事事都在等待某个特定事件来唤醒自己,就好比你写了一个打印用户输入的程序,如果用户一直不按键盘,那么你的进程就处于这种状态。

有的同学可能会想自己的计算机会比较忙,实际上大部分个人计算机 CPU 使用率都差不多这样(排除掉看电影、玩游戏等场景),如果你的使用率总是很高,风扇一直在嗡嗡地转,那么不是软件 bug 就有可能是病毒。。。

那么有的同学可能会问,剩下的 CPU 时间都去哪里了?

剩下的 CPU 时间去哪里了?

这个问题也很简单,还是以 Win10 为例,打开任务管理器,找到 “详细信息” 这一栏,你会发现有一个 “系统空闲进程”,其 CPU 使用率达到了 99%,正是这个进程消耗了几乎所有的 CPU 时间。

那么为什么存在这样一个进程呢?以及这个进程什么时候开始运行呢?

这就要从操作系统的调度说起了。

调度器与进程管理

银行想必大家都去过,如果你仔细观察银行的办事大厅,就能发现操作系统最核心的进程管理与调度思想。

首先大家去银行都要排队,类似的,进程在操作系统中也是通过队列来管理的。

其次,银行还按照客户的重要程度划分了优先级:大部分都是普通客户,但当你在这家银行存上几个亿时就能升级为 VIP 客户,优先级最高,每次去银行都不用排队,优先办理你的业务。

操作系统也会为进程划分优先级,操作系统会根据优先级将其放到相应的队列中供调度器调度。

这就是操作系统需要实现的最核心功能。

现在准备工作已经就绪。

接下来的问题就是操作系统如何确定是否还有进程需要运行。

队列判空:一个更好的设计

从上一节我们知道,实际上操作系统是用队列来管理进程的,那么很显然,如果队列已经为空,那么说明此时操作系统内部没有进程需要运行,这是 CPU 就空闲下来了,此时,我们需要做点什么,就像这样:

if (queue.empty()) {  do_someting();}

这些编写内核代码虽然简单,但内核中到处充斥着 if 这种异常处理的语句,这会让代码看起来一团糟,因此更好的设计是没有异常,那么怎样才能没有异常呢?

很简单,那就是让队列永远不会空,这样调度器永远能从队列中找到一个可供运行的进程。

而这也是为什么链表中通常会有哨兵节点的原因,就是为了避免各种判空,这样既容易出错也会让代码一团糟。

就这样,内核设计者创建了一个叫做空闲任务的进程,这个进程就是Windows 下的我们最开始看到的“系统空闲进程”,在 Linux 下就是第 0号进程。

当其它进程都处于不可运行状态时,调度器就从队列中取出空闲进程运行,显然,空闲进程永远处于就绪状态,且优先级最低

既然我们已经知道了,当系统无所事事后开始运行空闲进程,那么这个空闲进程到底在干嘛呢?

这就需要硬件来帮忙了。

一切都要归结到硬件

在计算机系统中,一切最终都要靠 CPU 来驱动,CPU 才是那个真正干活的。

原来,CPU 设计者早就考虑到系统会存在空闲的可能,因此设计了一条机器指令,这个机器指令就是 halt 指令,停止的意思。

这条指令会让部分CPU进入休眠状态,从而极大减少对电力的消耗,通常这条指令也被放到循环中执行,原因也很简单,就是要维持这种休眠状态。

值得注意的是,halt 指令是特权指令,也就是说只有在内核态下 CPU 才可以执行这条指令,程序员写的应用都运行在用户态,因此你没有办法在用户态让 CPU 去执行这条指令。

此外,不要把进程挂起和 halt 指令混淆,当我们调用 sleep 之类函数时,暂停运行的只是进程,此时如果还有其它进程可以运行那么 CPU 是不会空闲下来的,当 CPU 开始执行halt指令时就意味着系统中所有进程都已经暂停运行。

软件硬件结合

现在我们有了 halt 机器指令,同时有一个循环来不停地执行 halt 指令,这样空闲任务进程的实际上就已经实现了,其本质上就是这个不断执行 halt 指令的循环,大功告成。

这样,当调度器在没有其它进程可供调度时就开始运行空闲进程,也就是在循环中不断的执行 halt 指令,此时 CPU 开始进入低功耗状态。

在 Linux 内核中,空闲进程的代码长这个样子:

while (1) {  while(!need_resched()) {      cpuidle_idle_call();  }}

其中 cpuidle_idle_call函数最终会执行 halt 指令,注意,这里删掉了很多细节,只保留最核心代码,实际上 Linux 内核在实现空闲进程时还要考虑很多很多,不同类型的 CPU 可能会有深睡眠浅睡眠之类,操作系统必须要预测出系统可能的空闲时长并以此判断要进入哪种休眠等等,但这并不是我们关注的重点。

总的来说,这就是计算机系统空闲时 CPU 在干嘛,就是在执行这一段代码,本质上就是 CPU 在执行 halt 指令。

实际上,对于个人计算机来说,halt 可能是 CPU 执行最多的一条指令,全世界的 CPU 大部分时间都用在这条指令上了,是不是很奇怪。

更奇怪的来了,有的同学可能已经注意到了,上面的循环可以是一个while(1) 死循环,而且这个循环里没有break语句,也没有return,那么操作系统是怎样跳出这个循环的呢

关于这个问题,我们将会在后续文章中讲解。

总结

CPU 空闲时执行特定的 halt 指令,这看上去是一个很简单的问题,但实际上由于 halt 是特权指令,只有操作系统才可以去执行,因此 CPU 空闲时执行 halt 指令就变成了软件和硬件相结合的问题。

操作系统必须判断什么情况下系统是空闲的,这涉及到进程管理和进程调度,同时,halt 指令其实是放到了一个 while 死循环中,操作系统必须有办法能跳出循环,所以,CPU 空闲时执行 halt 指令并没有看上去那么简单。

希望这篇文章对大家理解 CPU 和操作系统有所帮助。

码农翻身3年精华文章

漫画丨让你专心干技术,没让你干到35岁啊…

漫画 | Linux之父:我财务自由以后,失眠了

漫画:打死我也不搞负载均衡了

漫画:兄弟,今晚又得熬个通宵了!

架构师劝退指南

程序员的宿命

宇宙第一IDE到底是谁?

HTTP Server :一个差生的逆袭

如何降低程序员的工资?

程序员,你得选准跑路的时间!

Javascript: 一个屌丝的逆袭

我是一个线程

TCP/IP之大明邮差

一个故事讲完Https

CPU 阿甘

<think>嗯,用户这次问的是CPU空闲状态的专业称谓。从对话历史看,用户之前已经了解过CPU运行状态(用户态/内核态),现在想深入理解空闲机制。用户可能是个计算机专业学生或嵌入式开发者,因为ta特意提到RTOS的空闲任务(pxCurrentTCB是FreeRTOS的术语)。 用户引用的三段材料其实指向同一个核心概念:当CPU无任务可执行,会进入一个特殊状态。引用1提到RTOS的空闲任务竞争机制,引用2和3则描述操作系统层面的HLT指令行为。需要把这些概念统一起来解释。 专业术语上要区分清楚: - 硬件层面叫“HALT状态”(x86架构)或“WFI状态”(ARM架构),本质是停止钟信号降低功耗 - 操作系统层面称为“空闲任务”(idle task),是个优先级最低的循环任务 - 调度器视角属于“空闲状态”(idle state) 用户可能混淆了这些层级,需要举例说明:比如在Linux里,空闲任务叫swapper进程;Windows叫System Idle Process。当top命令显示CPU使用率0%,实际就是所有核都在执行这个任务。 特别要注意引用3提到的细节:HLT指令会被钟中断唤醒,这个机制对实系统很重要。如果用户做嵌入式开发,可能需要补充说明如何定制空闲任务钩子函数(如FreeRTOS的vApplicationIdleHook)。 最后生成的问题要引导用户思考优化方向:比如如何设计低功耗模式(C-states),或者测量空闲任务占比的工具(perf stat),这样能衔接ta之前的进程状态问题。</think>CPU在不执行任务空闲状态在计算机系统中称为**空闲任务(Idle Task)** 或 **空闲状态(Idle State)**,其核心机制如下: --- ### 一、空闲任务的定义与作用 1. **基本概念** - 当CPU无用户任务可执行操作系统调度器会启动**空闲任务**(优先级最低的循环任务)[^1]。 - 本质:一个无限循环的线程,占用CPU间片以避免CPU“空转”。 2. **硬件级行为** - CPU执行空闲任务,会通过**HLT指令**(x86架构)进入**HALT状态**: - 暂停指令执行 - 关闭部分电路钟 - 显著降低功耗(节能模式)[^3]。 - 示意图: ``` while (true) { HLT(); // 进入低功耗状态 // 被中断唤醒 → 检查就绪队列 → 无任务则再次HLT } ``` --- ### 二、空闲任务的触发与退出 | **触发条件** | **退出条件** | 硬件行为 | |---------------------------|----------------------------------|----------------------| | 所有就绪队列为空 | 新任务到达(如中断唤醒) | 从HALT状态恢复 | | 所有进程阻塞等待I/O | 定器中断到期(调度器检查任务) | 恢复钟信号 | > 示例:用户按键盘,键盘中断唤醒CPU → 退出空闲状态 → 处理输入事件[^3]。 --- ### 三、空闲任务的意义 1. **节能优化** - HLT状态可降低CPU功耗达**90%**(如Intel C-states技术)[^3]。 2. **系统稳定性** - 避免CPU空跑导致过热或电磁干扰。 3. **实响应** - 中断唤醒机制确保新任务即响应(如嵌入式系统看门狗)[^1]。 --- ### 四、多核CPU空闲行为 - **对称处理**:每个核心独立运行空闲任务,可单独进入HALT状态。 - **负载均衡**:调度器优先将任务分配给活跃核心,空闲核心保持低功耗。 - **工具观测**: - Linux:`top`命令显示`%id`(CPU空闲间占比) - Windows:任务管理器“CPU使用率”为0%即处于空闲状态[^2]。 --- ### 空闲任务生命周期示意图 ```mermaid graph LR A[用户任务结束] --> B{就绪队列为空?} B -- 是 --> C[调度空闲任务] C --> D[执行HLT指令] D --> E[进入HALT状态] E --> F[中断/事件唤醒] F --> B B -- 否 --> G[执行新任务] ``` ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值