C++ 多线程实战 01|为什么需要线程:并发 vs 并行,进程 vs 线程
目录
一、为什么要学习多线程?
二、进程与线程的区别
1. 什么是进程?
2. 什么是线程?
3. 直观对比
三、并发 vs 并行
四、线程在程序中怎么工作?
五、代码示例:Hello, Thread!
运行效果
六、常见误区
七、练习题
八、总结
一、为什么要学习多线程?
想象一下你在写一个程序:
-
它要同时下载文件、显示下载进度、还要让用户能随时点击暂停按钮。
如果你用单线程来写,要么下载时界面卡死,要么响应界面时下载停掉。
解决方法就是 —— 多线程。
多线程能让程序同时处理多个任务,让应用更加流畅和高效。
但别急,我们先把几个基础概念理清楚,否则后面会很容易混淆。
二、进程与线程的区别
1. 什么是进程?
进程(Process)就是操作系统为一个正在运行的程序分配的独立资源空间。
-
每个进程有自己的 内存地址空间(代码段、数据段、堆、栈)。
-
进程之间一般是隔离的,不能直接访问对方的数据。
-
创建/销毁进程的开销比较大。
👉 可以把进程类比成“一个独立的公司”,有自己的办公室、员工和资源,外人进不来。
2. 什么是线程?
线程(Thread)是进程里的一个执行单元。
-
一个进程至少有一个线程(主线程)。
-
线程之间共享进程的地址空间(所以访问数据更方便)。
-
创建/切换线程的开销比进程小。
👉 线程就像是“公司里的员工”,大家共用同一个办公室和资料,但可以同时干不同的活。
3. 直观对比
项目 | 进程 | 线程 |
---|---|---|
地址空间 | 独立 | 共享 |
创建/切换开销 | 大 | 小 |
崩溃影响范围 | 一个进程崩溃一般不影响别的进程 | 一个线程崩溃可能拖垮整个进程 |
通信方式 | IPC(管道、消息队列等) | 共享内存,速度快 |
三、并发 vs 并行
这是很多初学者最容易混淆的概念。
-
并发(Concurrency):逻辑上“同时”执行,但实际上可能是在一颗 CPU 上快速切换。
👉 就像一个人同时看两本书:看一页 A → 翻页 → 看一页 B → 再翻页 → 回来继续 A。 -
并行(Parallelism):物理上真的同时执行,通常是多核 CPU 各干各的。
👉 就像两个人各拿一本书,各自读,不用切换。
📌 总结:
-
并发 = 时间上交错,提升“响应性”;
-
并行 = 空间上同时,提升“吞吐量”。
四、线程在程序中怎么工作?
-
每个线程有自己的 栈(用来保存局部变量、函数调用信息)。
-
线程共享 堆、全局变量、文件句柄 等资源。
-
操作系统调度器负责分配 CPU 时间片,决定哪个线程什么时候运行。
👉 换句话说:线程是操作系统调度的最小单位。
五、代码示例:Hello, Thread!
我们用一个最简单的例子来感受一下:
#include <iostream>
#include <thread>void say_hello(const std::string& name) {for (int i = 0; i < 5; i++) {std::cout << "Hello from " << name << " (i=" << i << ")\n";}
}int main() {std::thread t1(say_hello, "thread-1");std::thread t2(say_hello, "thread-2");t1.join(); // 等待 t1 完成t2.join(); // 等待 t2 完成std::cout << "Main thread finished.\n";return 0;
}
运行效果
输出可能是这样的(顺序会乱):
Hello from thread-1 (i=0)
Hello from thread-2 (i=0)
Hello from thread-1 (i=1)
Hello from thread-2 (i=1)
...
👉 这里可以看到,两个线程的输出交错在一起,说明它们是并发执行的。
六、常见误区
-
线程一定会让程序更快? ❌
-
如果任务是 I/O 密集(比如网络、文件),线程确实能提高效率。
-
但如果任务是纯计算密集(CPU 满载),线程数超过 CPU 核心数可能会更慢(上下文切换开销大)。
-
-
线程和进程谁更安全?
-
进程更独立,一个崩溃不会影响其他。
-
线程共享内存,出错时可能直接导致整个进程崩溃。
-
七、练习题
-
修改上面的代码,创建 4 个线程,分别打印不同的名字。
-
在主线程里也调用
say_hello("main")
,看看输出会怎样交错。 -
如果把
t1.join()
改成t1.detach()
,结果会发生什么?
八、总结
-
进程 = 程序的资源容器;线程 = 执行单元。
-
并发 ≠ 并行:并发是“切换”,并行是“同时”。
-
多线程的优势:提升程序响应性和吞吐量。
-
但多线程也带来新问题:同步、数据竞争、死锁……(后续章节逐步展开)。
👉 下一篇文章:
「线程生命周期全景:创建、运行、终止、回收」
我们将深入讨论线程的出生到消亡的全过程,以及 join
/detach
的区别。