std::condition_variable 应用举例

本文介绍了如何使用C++标准库中的`std::condition_variable`实现一个生产者-消费者模型,展示了在队列空时同步线程和等待条件的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::condition_variable 在多线程编程中非常有用,特别是当需要在多个线程之间同步或等待某个条件成立时。下面是一个简单的 std::condition_variable 的应用举例,演示了如何使用它来实现一个生产者-消费者模型。

在这个例子中,我们将有一个生产者线程向一个队列中添加数据,而一个消费者线程从队列中取出数据。我们将使用 std::condition_variable 来在队列为空时让消费者线程等待,以及在队列非空时通知消费者线程。

#include <iostream>  
#include <queue>  
#include <thread>  
#include <mutex>  
#include <condition_variable>  
  
std::queue<int> data_queue;  
std::mutex mtx;  
std::condition_variable cv;  
bool stop = false;  
  
// 生产者线程  
void producer() {  
    for (int i = 0; i < 10; ++i) {  
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时操作  
  
        std::lock_guard<std::mutex> lock(mtx);  
        data_queue.push(i);  
        std::cout << "Produced: " << i << std::endl;  
        cv.notify_one(); // 通知一个等待的线程  
    }  
  
    // 通知所有等待的线程,我们即将停止  
    {  
        std::lock_guard<std::mutex> lock(mtx);  
        stop = true;  
    }  
    cv.notify_all();  
}  
  
// 消费者线程  
void consumer() {  
    while (true) {  
        std::unique_lock<std::mutex> lock(mtx);  
        cv.wait(lock, []{ return !data_queue.empty() || stop; }); // 等待数据或停止信号  
  
        if (stop && data_queue.empty()) {  
            // 如果收到停止信号且队列为空,则退出循环  
            break;  
        }  
  
        int data = data_queue.front();  
        data_queue.pop();  
        lock.unlock(); // 在处理数据之前解锁,以避免长时间持有锁  
  
        std::cout << "Consumed: " << data << std::endl;  
        // ... 在这里处理数据 ...  
    }  
}  
  
int main() {  
    std::thread producer_thread(producer);  
    std::thread consumer_thread(consumer);  
  
    producer_thread.join();  
    consumer_thread.join();  
  
    return 0;  
}

在这个例子中,生产者线程向 data_queue 中添加数据,并通过 cv.notify_one() 通知等待的消费者线程。消费者线程使用 cv.wait() 等待数据,直到队列非空或收到停止信号。当消费者线程被唤醒时,它会检查队列是否为空或是否收到停止信号,并据此决定是否继续处理数据或退出循环。

注意,我们在处理数据之前释放了互斥锁(通过 lock.unlock()),以避免在处理数据期间长时间持有锁,从而允许其他线程访问队列。然而,在实际应用中,你需要确保在释放锁之后重新获取锁之前,你的代码是线程安全的。在这个例子中,由于我们只是简单地打印数据,所以没有问题。但在更复杂的场景中,你可能需要更复杂的同步机制来确保线程安全。

运行结果:

Produced: 0
Consumed: 0
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
Produced: 3
Consumed: 3
Produced: 4
Consumed: 4
Produced: 5
Consumed: 5
Produced: 6
Consumed: 6
Produced: 7
Consumed: 7
Produced: 8
Consumed: 8
Produced: 9
Consumed: 9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值