0
点赞
收藏
分享

微信扫一扫

std::condition_variable 如何工作?

std::condition_variable 是 C++ 标准库中用于线程同步的工具之一,它允许一个或多个线程等待某个条件的发生。std::condition_variable 通常与互斥锁(std::mutex)一起使用,以实现线程间的同步和通信。

一、基本概念

std::condition_variable 的主要功能是允许线程在某个条件不满足时进入休眠状态,并在条件满足时被唤醒。它通常用于实现生产者-消费者模式、线程间同步等场景。

二、工作原理

  1. 互斥锁(Mutex)
  • std::condition_variable 需要与一个互斥锁(std::mutex)一起使用,以确保线程安全。
  • 互斥锁用于保护共享资源,防止多个线程同时访问。
  1. 等待条件(Wait)
  • 线程可以通过 waitwait_for 方法进入休眠状态,直到条件变量被通知(notify)。
  • wait 方法会释放互斥锁,并使线程进入休眠状态,直到条件变量被通知。
  • wait_for 方法会释放互斥锁,并使线程进入休眠状态,直到条件变量被通知或超时。
  1. 通知条件(Notify)
  • 通过 notify_onenotify_all 方法通知等待的线程。
  • notify_one 唤醒一个等待的线程。
  • notify_all 唤醒所有等待的线程。

三、示例代码

以下是一个简单的生产者-消费者示例,展示如何使用 std::condition_variable 实现线程间的同步。

生产者-消费者示例

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

std::queue<int> dataQueue;
std::mutex mtx;
std::condition_variable cv;
bool done = false;

void producer() {
    for (int i = 0; i < 10; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        dataQueue.push(i);
        lock.unlock();
        cv.notify_one(); // 通知消费者
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产时间
    }

    {
        std::unique_lock<std::mutex> lock(mtx);
        done = true;
    }
    cv.notify_all(); // 通知所有消费者
}

void consumer(int id) {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !dataQueue.empty() || done; }); // 等待条件

        if (done && dataQueue.empty()) {
            break; // 如果生产者完成且队列为空,退出
        }

        int data = dataQueue.front();
        dataQueue.pop();
        lock.unlock();

        std::cout << "Consumer " << id << " processed data: " << data << std::endl;
    }
}

int main() {
    std::thread producerThread(producer);
    std::thread consumerThread1(consumer, 1);
    std::thread consumerThread2(consumer, 2);

    producerThread.join();
    consumerThread1.join();
    consumerThread2.join();

    return 0;
}

四、关键点解释

  1. 互斥锁(Mutex)
  • std::mutex mtx 用于保护共享资源 dataQueue,防止多个线程同时访问。
  1. 条件变量(Condition Variable)
  • std::condition_variable cv 用于线程间的同步,允许线程在条件不满足时进入休眠状态。
  1. 等待条件(Wait)
  • cv.wait(lock, [] { return !dataQueue.empty() || done; }); 释放互斥锁并使线程进入休眠状态,直到条件变量被通知。
  • cv.wait 的第二个参数是一个谓词,用于检查条件是否满足。如果条件不满足,线程将继续休眠。
  1. 通知条件(Notify)
  • cv.notify_one(); 唤醒一个等待的线程。
  • cv.notify_all(); 唤醒所有等待的线程。

五、注意事项

  1. 避免死锁
  • 确保在调用 waitwait_for 之前已经锁定了互斥锁。
  • 确保在通知条件变量之前释放互斥锁。
  1. 避免虚假唤醒
  • 使用谓词来检查条件是否真正满足,避免虚假唤醒导致的逻辑错误。
  1. 线程安全
  • 确保所有对共享资源的访问都在互斥锁的保护下进行。

六、总结

std::condition_variable 是 C++ 标准库中用于线程同步的强大工具。通过与互斥锁(std::mutex)一起使用,可以实现线程间的高效同步和通信。在生产者-消费者模式、线程间同步等场景中,std::condition_variable 提供了简洁且高效的解决方案。

举报

相关推荐

0 条评论