std::condition_variable

1.概要

std::condition_variable

2.内容

std::condition_variable 是 C++ 标准库中用于线程间同步的一种机制。它允许一个或多个线程等待某个条件成立,并在条件满足时被唤醒以继续执行。这种机制在需要等待某个事件发生或某个条件变为真时非常有用,比如等待数据准备好、等待某个资源可用等场景。

基本用法

std::condition_variable 通常与 std::mutex(互斥锁)一起使用,以确保在检查条件、等待条件变化以及修改条件时的线程安全。使用 std::condition_variable 时,一般需要以下几个步骤:

  1. 定义条件变量和互斥锁:首先,你需要定义一个 std::condition_variable 对象和一个 std::mutex 对象。

  2. 等待线程:在需要等待条件的线程中,使用 std::condition_variable 的 wait 方法。这个方法会原子性地解锁互斥锁并使当前线程阻塞,直到另一个线程通知条件已经满足。wait 方法通常会在一个循环中调用,以便在条件满足之前处理可能的虚假唤醒(spurious wakeups)。

  3. 通知线程:在条件满足时,由另一个线程调用 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::unique_lock-优快云博客

std::condition_variable-优快云博客 

std::future和std::promise-优快云博客 

gnome-session-properties-优快云博客 

4.关联知识 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值