C++中的条件变量(condition
C++中的条件变量(condition
在编程中,我们经常需要处理多个任务,这些任务可能需要同时运行,也可能需要按照一定的顺序运行。这就涉及到了线程的概念。线程就像是一个小程序,它可以在程序中独立运行,而且可以和其他线程并行执行。
但是,有时候我们需要控制线程的执行顺序,比如有两个线程A和B,我们希望A执行完后,B才能开始执行。这就需要一种机制来同步线程的执行,这就是条件变量(std::condition_variable
)的作用。
条件变量是一种特殊的变量,它可以让一个线程在某个条件成立之前等待,当条件成立时,这个线程就可以继续执行。条件变量通常和另一种叫做互斥锁(std::mutex
)的东西一起使用,互斥锁可以保证在同一时间只有一个线程能访问某个资源。
假设我们有两个线程A和B,我们希望A执行完后,B才能开始执行。我们可以这样做:
- 创建一个条件变量和一个互斥锁。
- 在A线程中,我们先锁定互斥锁,然后执行A线程的任务,任务完成后,我们解锁互斥锁,并通知条件变量。
- 在B线程中,我们也先锁定互斥锁,然后让B线程等待条件变量。当A线程通知条件变量后,B线程就会被唤醒,然后执行B线程的任务。
条件变量有三个主要的方法:
wait
:这个方法会让当前线程等待,直到条件变量被通知。notify_one
:这个方法会唤醒一个等待的线程。notify_all
:这个方法会唤醒所有等待的线程。
让我们通过一个简单的实例来理解条件变量的使用。假设我们有两个线程,一个生产者线程和一个消费者线程。生产者线程负责生成数据,消费者线程负责处理数据。我们希望当生产者线程生成了数据后,消费者线程才开始处理数据。
首先,我们需要包含必要的头文件,并定义一些全局变量:
代码语言:cpp代码运行次数:0运行复制#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false; // 用于表示数据是否已经生成
然后,我们定义生产者线程的函数:
代码语言:cpp代码运行次数:0运行复制void producer() {
std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟数据生成过程
std::lock_guard<std::mutex> lock(mtx);
ready = true; // 数据已经生成
_one(); // 通知消费者线程
}
接着,我们定义消费者线程的函数:
代码语言:cpp代码运行次数:0运行复制void cumer() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{return ready;}); // 等待数据生成
std::cout << "Cumer thread is processing data...\n";
// 模拟数据处理过程
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Data processed.\n";
}
最后,我们在主函数中启动这两个线程:
代码语言:cpp代码运行次数:0运行复制int main() {
std::thread t1(producer);
std::thread t2(cumer);
t1.join();
t2.join();
return 0;
}
运行这个程序,你会看到消费者线程会等待生产者线程生成数据,当数据生成后,消费者线程才开始处理数据。
在上述的生产者消费者问题中,我们只有一个生产者和一个消费者。但在实际的应用中,我们可能会有多个生产者和消费者。此时,我们需要使用一个队列来存储数据,生产者将数据放入队列,消费者从队列中取出数据。
首先,我们需要定义一个队列和一些全局变量:
代码语言:cpp代码运行次数:0运行复制#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> data_queue; // 数据队列
bool finished = false; // 用于表示生产者是否已经完成数据生成
然后,我们定义生产者线程的函数:
代码语言:cpp代码运行次数:0运行复制void producer(int id) {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟数据生成过程
std::lock_guard<std::mutex> lock(mtx);
data_queue.push(i);
std::cout << "Producer " << id << " produced data " << i << std::endl;
_one(); // 通知消费者线程
}
}
接着,我们定义消费者线程的函数:
代码语言:cpp代码运行次数:0运行复制void cumer(int id) {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{return !data_() || finished;}); // 等待数据生成
while (!data_()) {
int data = data_queue.front();
data_queue.pop();
std::cout << "Cumer " << id << " cumed data " << data << std::endl;
// 模拟数据处理过程
std::this_thread::sleep_for(std::chrono::seconds(1));
}
if (data_() && finished) {
break;
}
}
}
最后,我们在主函数中启动这些线程:
代码语言:cpp代码运行次数:0运行复制int main() {
std::thread producers[2];
std::thread cumers[2];
for (int i = 0; i < 2; ++i) {
producers[i] = std::thread(producer, i + 1);
cumers[i] = std::thread(cumer, i + 1);
}
for (auto &p : producers) {
p.join();
}
finished = true;
_all();
for (auto &c : cumers) {
c.join();
}
return 0;
}
在这个例子中,我们有两个生产者和两个消费者。生产者将数据放入队列,消费者从队列中取出数据。当所有的生产者都完成数据生成后,我们设置finished
为true
,并通知所有的消费者线程。
这就是如何使用条件变量来解决多生产者和多消费者的问题。通过使用条件变量,我们可以实现更复杂的线程同步需求。
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 17 条评论) |
本站网友 雾里看花水中望月 | 16分钟前 发表 |
本站网友 荔江美筑 | 2分钟前 发表 |
我们设置finished为true | |
本站网友 何为荣 | 12分钟前 发表 |
1. 什么是条件变量?条件变量是一种特殊的变量 | |
本站网友 许家印后台背景强硬 | 25分钟前 发表 |
cumers) { c.join(); } return 0; }在这个例子中 | |
本站网友 北京牛街 | 17分钟前 发表 |
我们希望A执行完后 | |
本站网友 mb什么意思 | 8分钟前 发表 |
C++中的条件变量(condition 生成带比例的小猫图片 (1).png在编程中 | |
本站网友 mteam | 17分钟前 发表 |
本站网友 心律失常的护理 | 6分钟前 发表 |
本站网友 梦见被狗咬手指 | 15分钟前 发表 |
chrono | |
本站网友 耐磨破碎机锤头 | 11分钟前 发表 |
本站网友 沙棘是什么 | 3分钟前 发表 |
lock_guard<std | |
本站网友 上海个人房屋出租 | 10分钟前 发表 |
本站网友 北京经济技术开发区 | 9分钟前 发表 |
一个生产者线程和一个消费者线程 | |
本站网友 惠州个人二手房网 | 17分钟前 发表 |
而且可以和其他线程并行执行 | |
本站网友 体毛怎么种植 | 17分钟前 发表 |
本站网友 李海生 | 0秒前 发表 |
但是 |