元气日常

程序中使用多线程的目的是为了提高cpu的利用率吗,为什么不采用多线程cpu利用率就不高呢

这是一个非常深刻且直击本质的问题!要解开这个疑惑,我们需要先区分两个概念:“CPU 利用率(CPU Utilization)”和“系统吞吐量(Throughput)”。

简单来说:程序使用多线程,主要目的并不是为了提高 CPU 利用率,而是为了提高系统的整体吞吐量(即单位时间内完成的任务数)。

我们可以从以下几个层面来剖析为什么“不采用多线程,CPU 利用率就不高”:

1. 核心原因:线程的“等待(阻塞)”状态在绝大多数实际应用中(如 Web 服务器、数据库、网络请求),程序大部分时间并不是在疯狂进行数学计算,而是在等待:

等待网络数据包到达(网络 I/O)等待数据从硬盘读取(磁盘 I/O)等待数据库返回结果等待锁的释放当单线程遇到这些“等待”时,它会进入阻塞状态。 此时,CPU 处于空闲状态,什么都不做,CPU 利用率就会断崖式下跌,甚至降到 0%。

多线程的作用: 当线程 A 在等待网络 I/O 时,操作系统会把 CPU 调度给线程 B 去执行其他任务。这样,CPU 始终有事可做,CPU 利用率自然就提高了。

2. 为什么 Redis 不需要多线程来提高 CPU 利用率?结合你引用的内容,Redis 之所以能“任性”地采用单线程,是因为它完美避开了上述的“等待”陷阱:

纯内存操作: Redis 的数据都在内存中,没有磁盘 I/O 的等待。非阻塞 I/O 多路复用: 它使用 epoll 等机制,在等待网络 I/O 时,主线程不会真的阻塞挂起,而是去处理其他准备好的连接。命令执行极快: 单次命令执行通常是微秒级的。结论: 因为 Redis 的主线程几乎永远不阻塞,它一直在高速运转,所以它的单核 CPU 利用率其实是非常高的(经常能跑到 100%)。既然单核已经满载且没有 I/O 等待,自然就不需要多线程来“填补 CPU 的空闲时间”了。

3. 多线程的真正目的:榨干多核性能与提高并发既然单线程也能把单核 CPU 跑满,为什么现代程序还要用多线程?

利用多核 CPU: 单线程再强,也只能用满 1 个 CPU 核心。如果你的服务器有 32 个核心,单线程程序最多只用 3.125% 的 CPU 算力。多线程可以将任务拆分到多个核心上并行计算,极大提高整体 CPU 利用率。应对真正的 CPU 密集型任务: 比如视频编解码、复杂加密算法、AI 模型推理。这些任务没有 I/O 等待,全是纯计算。单线程算需要 10 秒,32 个线程并行算可能只需要 0.5 秒。总结对比I/O 密集型

(如传统 Web 服务)

线程频繁阻塞等待,CPU 大量时间空闲,

CPU 利用率极低

线程 A 等待时,线程 B 顶上,CPU 持续工作,

CPU 利用率高

提高吞吐量,掩盖 I/O 延迟

内存极速操作

(如 Redis 核心逻辑)

几乎不阻塞,单核

CPU 利用率极高

引入多线程反而增加锁竞争和上下文切换,得不偿失

保持低延迟,简化并发控制

CPU 密集型

(如复杂计算)

跑满单核,

单核 CPU 利用率 100%

多核并行,

整体 CPU 利用率接近 100%

缩短计算时间,利用多核算力

所以,回到你的问题:不采用多线程时,CPU 利用率不高,并不是因为 CPU 算得慢,而是因为单线程在“发呆(等待 I/O)”。多线程就像是给 CPU 找了多个“打工人”,确保 CPU 这个“老板”永远有活可派。而 Redis 的主线程是个“超级卷王”,从不发呆,所以一个“打工人”就够了。