C++ 条件变量与线程通知机制:std::condition_variable

✅ 简介

  • std::condition_variable 是 C++11 引入的线程间通信机制,允许线程在某个条件满足时被唤醒。
  • 通常与 std::mutex 一起配合使用,用于实现生产者-消费者模型、线程等待任务等场景。

🔄 基本原理

  • 一个线程调用 wait() 进入阻塞状态,直到另一个线程调用 notify_one()notify_all()
  • wait() 会自动释放传入的 mutex,并在被唤醒时重新获取锁。

⚠️ 虚假唤醒(Spurious Wakeup)

  • 调用 wait() 的线程有可能在没有收到通知时被唤醒 ,这被称为虚假唤醒

  • 因此,推荐使用带谓词版本的 wait(lock, predicate) 形式:

    cpp 复制代码
    cv.wait(lock, []{ return 条件满足; });
  • 这样即使发生虚假唤醒,wait 也会再次检查条件是否成立,确保线程只有在需要时才继续执行。


🔧 使用方式

示例:生产者-消费者模型(含虚假唤醒处理)

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <atomic>
#include <csignal>
#include <chrono>

std::mutex mtx;
std::condition_variable cv;
std::queue<int> dataQueue;
std::atomic<bool> stop{false};

// 信号处理函数,捕获 Ctrl+C
void signalHandler(int signum) {
    stop = true;
    cv.notify_all(); // 通知所有等待的线程
}

void producer() {
    int i = 0;
    while (!stop) {
        {
            std::unique_lock<std::mutex> lock(mtx);
            dataQueue.push(i);
            std::cout << "Produced: " << i << std::endl;
            ++i;
        }
        cv.notify_one(); // 通知一个等待的线程
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠 1 秒
    }
    cv.notify_all(); // 通知消费者停止
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !dataQueue.empty() || stop; }); // 等待数据或停止信号

        if (!dataQueue.empty()) {
            std::cout << "Consumed: " << dataQueue.front() << std::endl;
            dataQueue.pop();
            lock.unlock(); // 提前解锁以减少锁持有时间
            std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠 1 秒
        } else if (stop) {
            break; // 队列为空且收到停止信号,退出
        }
    }
}

int main() {
    // 注册信号处理函数
    std::signal(SIGINT, signalHandler);

    std::thread t1(producer);
    std::thread t2(consumer);

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

    return 0;
}

☑️ 关键函数说明

函数名 说明
wait(lock) 等待并释放锁,直到 notify_one 被调用。⚠️ 可能发生虚假唤醒。
wait(lock, predicate) 带条件的等待,直到 predicate 返回 true。✅ 推荐用法
notify_one() 唤醒一个等待的线程。
notify_all() 唤醒所有等待的线程。

📌 总结

特性 描述
同步机制 用于线程之间的通信
等待效率 阻塞等待,不占用 CPU
虚假唤醒 可能无通知就被唤醒,需使用谓词保护
适用场景 生产者-消费者、线程池任务调度等
配套使用 std::mutex + std::unique_lock 配合
相关推荐
愚润求学19 分钟前
【Linux】动静态库链接原理
linux·运维·服务器·开发语言·笔记
呦呦彬27 分钟前
【问题排查】easyexcel日志打印Empty row!
java·开发语言·log4j
Tummer836338 分钟前
C#+WPF+prism+materialdesign创建工具主界面框架
开发语言·c#·wpf
九章云极AladdinEdu44 分钟前
GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践
java·开发语言·人工智能·深度学习·测试工具·负载均衡·transformer
天上路人1 小时前
AI神经网络降噪算法在语音通话产品中的应用优势与前景分析
深度学习·神经网络·算法·硬件架构·音视频·实时音视频
好吃的肘子1 小时前
MongoDB 应用实战
大数据·开发语言·数据库·算法·mongodb·全文检索
ghost1431 小时前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#
小白学大数据1 小时前
Scrapy框架下地图爬虫的进度监控与优化策略
开发语言·爬虫·python·scrapy·数据分析
立秋67891 小时前
用Python绘制梦幻星空
开发语言·python·pygame
汉克老师1 小时前
GESP2025年3月认证C++二级( 第三部分编程题(1)等差矩阵)
c++·算法·矩阵·gesp二级·gesp2级