在并发编程中,'锁'是解决资源竞争、保证数据一致性的核心工具 —— 无论是多线程共享进程内资源,还是多进程跨地址空间协作,都需要通过锁来规范临界区的访问逻辑。本文结合 C/C++ 开发场景(含 Linux 系统调用、C++11 + 标准库),系统梳理多线程 / 多进程中常用锁的种类、核心特点,并给出实战选型建议。
一、核心概念铺垫
在讲锁之前,先明确两个关键前提,避免混淆:
- 临界区:并发场景中多个执行流(线程 / 进程)共同访问的共享资源(如全局变量、文件、网络连接),是锁的保护对象。
- 线程 vs 进程:
- 多线程:共享同一进程的地址空间,锁可直接基于进程内内存实现(开销小);
- 多进程:地址空间独立,锁需借助'跨进程共享资源'(如文件、共享内存)实现(开销略大)。
二、多线程锁(线程间同步)
多线程锁用于保护进程内的共享资源(如全局变量、堆内存),核心是'线程间互斥 / 同步',常见类型如下:
1. 互斥锁(Mutex):并发编程的'基础款'
核心特点
- 本质:二进制锁(要么锁定,要么解锁),保证同一时刻只有一个线程进入临界区。
- 等待机制:线程获取不到锁时,会从'运行态'转为'阻塞态',放弃 CPU 资源(不占用 CPU 空转)。
- 适用场景:临界区执行时间较长(如 IO 操作、复杂计算),避免 CPU 浪费。
- 优缺点:
- 优点:开销低、使用简单,无 CPU 空转;
- 缺点:上下文切换开销(阻塞 / 唤醒线程时),适合临界区耗时 > 上下文切换耗时的场景。
C++ 实战示例(C++11 标准库)
#include <mutex>
#include <thread>
std::mutex mtx; // 全局互斥锁
int shared_data = 0;
void increment() {
std::lock_guard<std::mutex> lock(mtx); // RAII 风格,自动加锁/解锁,避免漏解锁
shared_data++; // 临界区:保护共享变量
}
int main() {
std::thread t1(increment), t2(increment);
t1.join();
t2.();
;
}

