C++ 语言 多线程同步原语示例

C++阿木 发布于 2025-06-14 8 次阅读


阿木博主一句话概括:C++ 多线程同步原语示例解析

阿木博主为你简单介绍:
在多线程编程中,同步原语是确保线程间正确交互的关键机制。本文将围绕C++语言中的多线程同步原语进行探讨,通过具体的示例代码,展示互斥锁、条件变量、信号量等同步原语的使用方法,并分析其原理和适用场景。

一、
随着计算机技术的发展,多线程编程已成为提高程序性能的重要手段。多线程编程也带来了线程同步的问题。为了保证数据的一致性和程序的正确性,我们需要使用同步原语来协调线程间的操作。本文将详细介绍C++中的几种常见同步原语,并通过示例代码展示其使用方法。

二、互斥锁(Mutex)
互斥锁是一种最基本的同步原语,用于保护共享资源,确保同一时刻只有一个线程可以访问该资源。

cpp
include
include

std::mutex mtx; // 创建互斥锁

void printHello() {
mtx.lock(); // 加锁
std::cout << "Hello World" << std::endl;
mtx.unlock(); // 解锁
}

int main() {
std::thread t1(printHello);
std::thread t2(printHello);

t1.join();
t2.join();

return 0;
}

在上面的代码中,我们创建了一个互斥锁`mtx`,并在`printHello`函数中使用`lock()`和`unlock()`方法来加锁和解锁。这样,当多个线程同时调用`printHello`函数时,它们会按照一定的顺序执行,避免了数据竞争。

三、条件变量(Condition Variable)
条件变量用于线程间的同步,它允许一个或多个线程在某个条件不满足时等待,直到其他线程改变条件并通知它们。

cpp
include
include
include
include

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void waitTask() {
std::unique_lock lck(mtx);
cv.wait(lck, []{return ready;}); // 等待条件满足
std::cout << "Task is ready" << std::endl;
}

void notifyTask() {
std::unique_lock lck(mtx);
ready = true; // 改变条件
cv.notify_one(); // 通知一个等待的线程
}

int main() {
std::thread t1(waitTask);
std::thread t2(notifyTask);

t1.join();
t2.join();

return 0;
}

在上述代码中,`waitTask`函数会等待`ready`条件为`true`,而`notifyTask`函数会设置`ready`为`true`并通知一个等待的线程。这样,`waitTask`函数就可以在条件满足后继续执行。

四、信号量(Semaphore)
信号量是一种更高级的同步原语,它可以实现线程间的同步和互斥。

cpp
include
include
include

sem_t sem;

void task() {
sem_wait(&sem); // 等待信号量
std::cout << "Task is running" << std::endl;
sem_post(&sem); // 释放信号量
}

int main() {
sem_init(&sem, 0, 1); // 初始化信号量,初始值为1

std::thread t1(task);
std::thread t2(task);

t1.join();
t2.join();

sem_destroy(&sem); // 销毁信号量

return 0;
}

在上面的代码中,我们使用`sem_wait()`和`sem_post()`来控制线程的执行顺序。信号量`sem`的初始值为1,因此同一时刻只有一个线程可以执行`task`函数。

五、总结
本文通过具体的示例代码,介绍了C++中几种常见的多线程同步原语:互斥锁、条件变量和信号量。这些同步原语在多线程编程中扮演着重要的角色,能够帮助我们编写出正确、高效的并发程序。在实际应用中,应根据具体场景选择合适的同步原语,以确保线程间的正确交互和数据的一致性。