在大二自学Linux系统编程的路上,前面我初步学习了解了Makefile,文件io,进程处理和进程通讯,今天推开了多线程并发的大门,以此稿作学习记录。看起来简单的 lock 和 unlock,背后其实藏着操作系统复杂的调度逻辑。
一、 为什么要用互斥锁?
在多线程环境下,多个线程同时操作同一个共享变量(比如全局变量)时,如果不加控制,就会出现数据混乱(竞态条件)。
互斥锁(Mutex)就像一个房间的门锁,保证了同一时刻只有一个线程能进入房间操作数据。


200000个线程,结果应为200000,实际是199978,
这就是经典的竞态条件(Race Condition)。
看似一行简单的 (*p)++,在 CPU 底层其实分成了三步:
1. Read(读):把 num 的值从内存读进 CPU 寄存器。
2. Modify(改):寄存器里的值 +1。
3. Write(写):把新值写回内存。
因为 CPU 的时间片轮转机制,线程 A 刚把值读进寄存器,可能就被操作系统强行叫停了;此时线程 B 抢到了 CPU,完成加 1 并写回。等线程 A 再次醒来,它依然用脑子里记的“旧值”去加 1 并覆盖。这就导致了数据丢失。
二、怎么使用互斥锁?
全局定义互斥锁变量:pthread_mutex_t mutex;
<pthread.h>里有五种相关函数:
1).pthread_mutex_init(pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr):
初始化互斥锁 第二个参数是锁属性,NULL为默认
2).pthread_mutex_destroy(pthread_mutex_t* __mutex):
销毁互斥锁
3).pthread_mutex_lock(pthread_mutex_t *__mutex):
*阻塞*获取互斥锁
4).pthread_mutex_trylock(pthread_mutex_t *__mutex):
!非阻塞拿锁:锁被占用立刻返回非0
5).pthread_mutex_unlock(pthread_mutex_t *__mutex):
解锁
三、什么情况使用互斥锁?
当多个线程都需要访问同一个变量,同一个临界资源的时候,互斥锁能保证线程互斥的进行,从而保证结果的一致性。
本文深入解析Linux系统编程中pthread互斥锁(mutex)的核心机制,阐明其解决竞态条件的必要性:针对共享变量的非原子操作(读-改-写)在时间片切换下导致的数据不一致问题。详细说明pthread_mutex_t的声明、初始化、加锁(阻塞/非阻塞)、解锁及销毁五类API用法,并强调临界区保护场景。内容聚焦于POSIX线程同步原语在并发控制中的底层作用。
526

被折叠的 条评论
为什么被折叠?



