1.概要
std::condition_variable
2.内容
std::condition_variable
是 C++ 标准库中用于线程间同步的一种机制。它允许一个或多个线程等待某个条件成立,并在条件满足时被唤醒以继续执行。这种机制在需要等待某个事件发生或某个条件变为真时非常有用,比如等待数据准备好、等待某个资源可用等场景。
基本用法
std::condition_variable
通常与 std::mutex
(互斥锁)一起使用,以确保在检查条件、等待条件变化以及修改条件时的线程安全。使用 std::condition_variable
时,一般需要以下几个步骤:
-
定义条件变量和互斥锁:首先,你需要定义一个
std::condition_variable
对象和一个std::mutex
对象。 -
等待线程:在需要等待条件的线程中,使用
std::condition_variable
的wait
方法。这个方法会原子性地解锁互斥锁并使当前线程阻塞,直到另一个线程通知条件已经满足。wait
方法通常会在一个循环中调用,以便在条件满足之前处理可能的虚假唤醒(spurious wakeups)。 -
通知线程:在条件满足时,由另一个线程调用
std::condition_variable
的notify_one
或notify_all
方法来唤醒等待的线程。notify_one
唤醒一个等待该条件变量的线程(如果有的话),而notify_all
唤醒所有等待该条件变量的线程。
示例代码
以下是一个简单的示例,展示了如何使用 std::condition_variable
来同步两个线程:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id(int id) {
std::unique_lock<std::mutex> lck(mtx);
// 等待 ready 变为 true
cv.wait(lck, []{ return ready; });
// 打印线程 ID
std::cout << "Thread " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
// 通知所有等待的线程
cv.notify_all();
}
int main() {
std::thread threads[10];
// 创建 10 个线程
for (int i = 0; i < 10; ++i)
threads[i] = std::thread(print_id, i);
std::cout << "10 threads ready to race...\n";
go(); // 改变 ready 的值并通知所有线程
for (auto& th : threads) th.join();
return 0;
}
在这个例子中,10 个线程被创建,每个线程都等待 ready
变量变为 true
。主线程通过调用 go
函数来改变 ready
的值,并通过 cv.notify_all()
唤醒所有等待的线程。这样,所有线程就可以继续执行并打印它们的 ID 了。
注意事项
- 避免死锁:在使用
std::condition_variable
时,一定要确保在调用wait
之前已经锁定了互斥锁,并且在wait
返回后(即条件满足后),互斥锁仍然是被锁定的状态。 - 虚假唤醒:
wait
方法可能会因为系统原因而虚假唤醒(即没有收到通知也唤醒了)。因此,通常需要在wait
的循环中检查条件。 - 性能考虑:频繁地唤醒和等待可能会影响性能,特别是在高并发环境下。因此,应该合理设计条件变量的使用,以减少不必要的等待和唤醒。
3.关联链接
std::future和std::promise-优快云博客
gnome-session-properties-优快云博客
4.关联知识