条件变量用于多线程同步,需配合互斥锁使用。1. 包含头文件<condition_variable>,使用std::condition_variable和std::unique_lock;2. 等待线程获取锁后调用wait(),内部自动释放锁并等待唤醒;3. 通知线程修改共享数据后调用notify_one()或notify_all();4. 示例为生产者-消费者模型,生产者入队数据并通知,消费者在条件满足时出队;5. 注意处理虚假唤醒,应使用带谓词的wait,并在锁保护下修改共享状态。

在C++中,条件变量(condition variable)是多线程编程中用于线程间同步的重要工具。它通常与互斥锁(mutex)配合使用,允许某个线程等待特定条件成立,而另一个线程在条件达成时通知等待中的线程继续执行。
1. 头文件与基本组件
要使用条件变量,需要包含头文件 condition_variable:
#include <thread>
#include <mutex>
#include <condition_variable>
主要涉及的类有:
-
std::condition_variable:标准条件变量,需配合 std::unique_lock<std::mutex> 使用。
-
std::condition_variable_any:更通用,可配合任意满足锁概念的锁类型。
-
std::unique_lock:比 std::lock_guard 更灵活,支持延迟锁定和转移所有权,是条件变量的标准搭配。
2. 基本使用流程
典型使用模式包括等待和通知两个部分:
立即学习“C++免费学习笔记(深入)”;
等待线程(消费者或等待者):
- 获取互斥锁(使用 unique_lock)。
- 调用 wait()、wait_for() 或 wait_until() 等待条件。
- 在 wait 内部会自动释放锁,直到被唤醒后重新获取锁再继续。
通知线程(生产者或触发者):
- 修改共享数据(如设置标志位、添加任务等)。
- 获取互斥锁并修改状态。
- 调用 notify_one() 唤醒一个等待线程,或 notify_all() 唤醒所有等待线程。
3. 示例代码:生产者-消费者模型
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
std::queue<int> data_queue;
std::mutex mtx;
std::condition_variable cv;
bool finished = false;
// 生产者函数
void producer() {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::unique_lock<std::mutex> lock(mtx);
data_queue.push(i);
std::cout << "生产: " << i << "\n";
lock.unlock();
cv.notify_one(); // 通知消费者
}
{
std::unique_lock<std::mutex> lock(mtx);
finished = true;
}
cv.notify_all(); // 通知所有消费者结束
}
// 消费者函数
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
// 等待队列非空或任务结束
cv.wait(lock, [] { return !data_queue.empty() || finished; });
if (!data_queue.empty()) {
int value = data_queue.front();
data_queue.pop();
std::cout << "消费: " << value << "\n";
}
if (data_queue.empty() && finished) {
break;
}
lock.unlock();
}
std::cout << "消费者退出\n";
}
int main() {
std::thread p(producer);
std::thread c(consumer);
p.join();
c.join();
return 0;
}
4. 关键注意事项
-
避免虚假唤醒:即使没有调用 notify,wait 也可能返回。因此必须使用循环检查条件,推荐使用带谓词的 wait 形式:
cv.wait(lock, []{ return condition; });
这种写法会自动处理虚假唤醒。
-
始终在锁保护下修改共享状态:通知前必须确保数据已正确更新,并且在互斥锁保护下进行。
-
notify 不需要加锁也能调用,但修改共享变量必须加锁。
- 选择 notify_one() 还是 notify_all() 取决于是否有多个线程在等待同一条件。
基本上就这些。条件变量的核心是“等待某个条件”,配合互斥锁安全地挂起和唤醒线程。掌握好 wait 和 notify 的时机,就能写出可靠的多线程协作逻辑。
以上就是c++++中如何使用条件变量_c++条件变量使用方法的详细内容,更多请关注php中文网其它相关文章!