智慧生活指南
第二套高阶模板 · 更大气的阅读体验

线程间同步的几种方式 实用操作步骤与避坑指南

发布时间:2026-01-16 21:51:40 阅读:321 次

在编写多线程程序时,多个线程常常需要共享数据或资源。就像一家人共用一个衣柜,衣服叠好、分类放好才能避免翻乱。如果谁想拿就拉开抽屉,结果可能就是袜子乱飞、衬衫皱成一团。线程之间也一样,没有规矩就会出乱子,这时候就需要“同步”来协调。

互斥锁(Mutex)

互斥锁就像是给共享资源加了一把锁。同一时间只能有一个线程持有这把锁,处理完之后才释放。比如两个人都想用厨房做饭,但灶台只能一个人用,拿到“灶台使用权”的人才能开火。

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);
// 操作共享资源
pthread_mutex_unlock(&lock);

信号量(Semaphore)

信号量像是管理停车位的系统。假设停车场有3个空位,信号量初始值就是3。每进一辆车减1,出来一辆加1。当值为0时,其他线程就得等着。它不只限于“有或无”,还能控制多个资源的并发访问。

#include <semaphore.h>
sem_t sem;
sem_init(&sem, 0, 3); // 允许最多3个线程进入

sem_wait(&sem);
// 访问资源
sem_post(&sem);

条件变量(Condition Variable)

有时候线程不能光靠抢锁,还得等某个条件成立。比如你等快递,不能一直开门看,而是等快递员打电话通知你。条件变量就是用来“等待 + 通知”的机制,常配合互斥锁使用。

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 等待方
pthread_mutex_lock(&mutex);
while (data_ready == 0) {
    pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);

// 通知方
pthread_mutex_lock(&mutex);
data_ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

自旋锁(Spinlock)

自旋锁有点像你站在微波炉前盯着转盘,不停地问“好了没”。它不会让线程睡眠,而是持续检查锁是否可用。适用于等待时间非常短的场景,省去了线程切换的开销,但会浪费CPU时间。

while (__sync_lock_test_and_set(&lock, 1)) {
    // 空循环,等待
}
// 进入临界区
__sync_lock_release(&lock);

读写锁(Read-Write Lock)

读写锁区分“读”和“写”操作。就像图书馆的书,很多人可以同时阅读同一本书,但只要有人想修改,就得清场。读锁可被多个线程共享,写锁则是独占的。

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

// 读线程
pthread_rwlock_rdlock(&rwlock);
// 读取数据
pthread_rwlock_unlock(&rwlock);

// 写线程
pthread_rwlock_wrlock(&rwlock);
// 修改数据
pthread_rwlock_unlock(&rwlock);