电脑学堂
第二套高阶模板 · 更大气的阅读体验

线程同步机制有哪些?常见方法一文讲清楚

发布时间:2026-01-08 13:30:27 阅读:199 次

线程同步机制有哪些?

在多线程编程中,多个线程同时访问共享资源时容易引发数据混乱。比如你写一个记账程序,两个线程同时往同一个账户扣钱,结果可能扣少了或多扣了。这时候就得靠线程同步机制来协调,保证操作的有序性。

互斥锁(Mutex)

最常用的同步手段就是互斥锁。它就像一把钥匙,只有拿到钥匙的线程才能进入临界区操作数据,其他线程只能排队等。用完之后要把钥匙交出去,让别人用。

在 C++ 中可以用 std::mutex 实现:

#include <mutex>
std::mutex mtx;

void thread_func() {
mtx.lock();
// 操作共享资源
mtx.unlock();
}

实际开发中建议用 lock_guard 这类 RAII 手段,避免忘记解锁。

信号量(Semaphore)

信号量可以控制同时访问某一资源的线程数量。比如你开了个网吧,最多允许10台机器同时上网,那就可以设一个初始值为10的信号量。每进来一个线程就减一,离开就加一。

POSIX 信号量示例:

#include <semaphore.h>
sem_t sem;

sem_init(&sem, 0, 3); // 允许3个线程同时访问
sem_wait(&sem); // P操作
// 访问资源
sem_post(&sem); // V操作

条件变量(Condition Variable)

有时候线程需要等某个条件成立才能继续执行。比如生产者往队列放数据,消费者得等队列不为空才能取。这时候光靠锁不行,得配合条件变量。

在 C++ 中常和 mutex 一起使用:

#include <condition_variable>
std::condition_variable cv;
std::mutex cv_m;
bool ready = false;

void waits() {
std::unique_lock<std::mutex> lk(cv_m);
cv.wait(lk, []{ return ready; });
// 条件满足后继续执行
}

读写锁(Read-Write Lock)

适用于读多写少的场景。比如配置文件,多个线程可以同时读,但写的时候必须独占。读写锁允许多个读线程并发,写线程则要排他。

pthread 提供了读写锁支持:

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

void read_data() {
pthread_rwlock_rdlock(&rwlock);
// 读操作
pthread_rwlock_unlock(&rwlock);
}

void write_data() {
pthread_rwlock_wrlock(&rwlock);
// 写操作
pthread_rwlock_unlock(&rwlock);
}

原子操作(Atomic Operations)

对于简单的变量操作,比如计数器自增,用锁可能有点重。原子操作由硬件直接支持,能保证一条指令完成读-改-写过程,不会被中断。

C++ 中可用 atomic 类型:

#include <atomic>
std::atomic<int> counter(0);

void increment() {
counter++; // 线程安全
}

这类操作效率高,但只适合简单场景,复杂逻辑还得靠锁。

这些机制各有适用场合。选对工具,程序才跑得稳又快。日常写代码时别一上来就加锁,先想清楚共享数据怎么访问,再决定用哪种方式同步。