【计算机基础速成】第十一课:线程同步、互斥与死锁
1. 这节课的目标
在学完进程和线程之后,面试官通常会继续追问:
- 什么是线程同步?
- 什么是互斥?
- 什么是临界区?
- 什么是死锁?
- 死锁的四个必要条件是什么?
- 如何避免死锁?
这节课学完后,你至少要做到:
- 知道为什么多线程需要同步
- 能说清临界区、互斥、同步是什么
- 能说清死锁是什么
- 能背出死锁四个必要条件
- 能回答几种常见避免死锁的方法
2. 为什么多线程需要同步
一句话理解
因为多个线程会共享资源,如果不加控制,就可能把数据弄乱。
举个例子
两个线程同时修改同一个变量:
count = count + 1理论上加两次应该得到 2,但实际并发执行时,结果可能不是 2。
所以问题的核心不是“线程多”,而是:
多个线程同时操作共享资源
这就是为什么需要同步控制。
3. 什么是临界区
一句话理解
临界区就是访问共享资源的那段代码。
面试标准答法
临界区指的是程序中访问共享资源的那部分代码。由于多个线程同时进入临界区可能导致数据不一致,因此通常需要通过同步机制来保护临界区。
怎么理解
只要一段代码里面操作了大家共用的数据,这段代码就很可能是临界区。
4. 什么是互斥
一句话理解
互斥就是同一时刻只允许一个线程进入临界区。
面试标准答法
互斥指的是在同一时刻,只允许一个线程访问某个共享资源或进入某个临界区,从而避免并发访问引发的数据冲突。
怎么理解
互斥更强调:
- 不要同时进去
- 一个进,另一个等
5. 什么是同步
一句话理解
同步是让多个线程按照一定顺序或规则协作执行。
面试标准答法
同步指的是多个线程之间按照一定的先后顺序或约束关系协调执行,以保证程序逻辑正确。互斥可以看作同步的一种特殊情况。
你可以这样区分
- 互斥:强调“同一时刻只能一个线程访问”
- 同步:强调“线程之间要配合好执行顺序”
6. 常见同步问题的本质
你现在不用深学各种具体工具实现,但要知道问题本质:
- 资源竞争
- 执行顺序不确定
- 共享数据可能被同时修改
所以后面才会有各种解决方式,比如:
- 锁
- 信号量
- 条件变量
你现在先知道这些名字即可。
7. 什么是死锁
这是操作系统里非常高频的经典题。
一句话理解
死锁就是多个线程或进程互相等待对方释放资源,结果大家都卡住了。
举个简单例子
线程 A 拿到了资源 1,等待资源 2。 线程 B 拿到了资源 2,等待资源 1。
于是:
- A 等 B
- B 等 A
最后谁也走不下去。
面试标准答法
死锁是指多个进程或线程在执行过程中,因为争夺资源而造成的一种互相等待现象,导致各方都无法继续执行。
8. 死锁为什么会发生
死锁不是随便就发生的,它通常要满足一些条件。
这就是面试必背内容:
死锁四个必要条件
9. 死锁的四个必要条件
这个一定要背。
- 互斥条件
- 请求并保持条件
- 不可剥夺条件
- 循环等待条件
9.1 互斥条件
资源一次只能被一个线程或进程占有。
9.2 请求并保持条件
已经持有资源的线程,在请求新资源时,不会先释放自己手里的资源。
9.3 不可剥夺条件
资源一旦被某个线程拿到,在使用完之前,其他线程不能强行抢走。
9.4 循环等待条件
多个线程之间形成一个互相等待资源的环。
面试标准答法
死锁发生通常需要同时满足四个必要条件:互斥条件、请求并保持条件、不可剥夺条件和循环等待条件。只要破坏其中任意一个条件,就可以避免死锁。
10. 如何避免死锁
这是经典追问题。
核心思路
既然死锁要满足四个必要条件,那么避免死锁的思路就是:
破坏其中至少一个条件
常见方法
方法 1:按固定顺序申请资源
比如统一要求:
- 先申请资源 A
- 再申请资源 B
这样可以破坏循环等待。
方法 2:一次性申请所有资源
避免“拿着一个再等另一个”。
这样可以破坏请求并保持条件。
方法 3:设置超时或回退机制
如果长时间拿不到资源,就主动释放已占有资源,稍后重试。
方法 4:尽量减少锁的嵌套和持有时间
让冲突概率降低。
面试标准答法
避免死锁的常见方法包括:按固定顺序申请资源、一次性申请所需资源、设置超时和回退机制,以及尽量减少锁嵌套和锁持有时间。本质上都是在破坏死锁形成的必要条件。
11. 死锁和线程安全的关系
你可以这样理解:
- 线程安全问题:多个线程把数据弄乱了
- 死锁问题:多个线程谁也走不动了
两者都和并发有关,但不是一回事。
面试理解
线程安全强调结果正确,死锁强调程序卡住不前。
12. 一套适合面试的完整答法
如果面试官问:
什么是死锁?怎么避免?
你可以这样答:
死锁是指多个线程或进程在执行过程中因为争夺资源而互相等待,
最终导致都无法继续执行的现象。
死锁通常需要满足四个必要条件:互斥条件、请求并保持条件、不可剥夺条件和循环等待条件。
避免死锁的思路就是破坏其中至少一个条件,
比如按固定顺序申请资源、一次性申请所有资源、设置超时和回退机制,
以及减少锁嵌套和锁持有时间等。如果面试官问同步和互斥,你可以接着说:
临界区是访问共享资源的代码区域,
互斥强调同一时刻只能有一个线程进入临界区,
同步则更强调多个线程之间按照一定顺序协调执行,
它们的目的都是为了保证并发场景下程序逻辑正确。13. 本课高频面试题
13.1 什么是临界区
标准回答
临界区是程序中访问共享资源的那部分代码,由于多个线程同时进入临界区可能导致数据不一致,因此通常需要同步机制来保护。
13.2 什么是互斥
标准回答
互斥指的是同一时刻只允许一个线程访问某个共享资源或进入某个临界区,从而避免并发访问导致的数据冲突。
13.3 什么是同步
标准回答
同步指的是多个线程按照一定顺序或约束关系协调执行,以保证程序逻辑正确。互斥可以看作同步的一种特殊情况。
13.4 什么是死锁
标准回答
死锁是指多个线程或进程在执行过程中因为争夺资源而互相等待,最终导致都无法继续执行的现象。
13.5 死锁的四个必要条件是什么
标准回答
死锁的四个必要条件分别是:互斥条件、请求并保持条件、不可剥夺条件和循环等待条件。
13.6 如何避免死锁
标准回答
避免死锁的常见方法包括:按固定顺序申请资源、一次性申请所有资源、设置超时和回退机制,以及尽量减少锁嵌套和锁持有时间。本质上是破坏死锁形成的必要条件。
14. 本课最小记忆卡片
卡片 1
- 临界区:访问共享资源的代码
卡片 2
- 互斥:同一时刻只允许一个线程进入
卡片 3
- 同步:多个线程按规则协调执行
卡片 4
- 死锁:互相等待资源,谁都走不动
卡片 5
- 死锁四条件
- 互斥
- 请求并保持
- 不可剥夺
- 循环等待
卡片 6
- 避免死锁:固定顺序申请、一次性申请、超时回退
15. 课后练习
15.1 口头复述题
请你尝试不看讲义回答:
- 为什么多线程需要同步?
- 什么是临界区?
- 什么是互斥?什么是同步?
- 什么是死锁?
- 死锁的四个必要条件是什么?
- 如何避免死锁?
15.2 今日最低完成标准
如果今天时间不多,至少完成下面任务:
- 背会本课 6 张最小记忆卡片
- 能背出死锁四个必要条件
- 能完整回答“什么是死锁,如何避免死锁”
16. 下一课预告
第十二课:内存管理、虚拟内存与分页