条件变量(Condition Variable)是一种同步机制,用于多线程编程中,允许线程等待某个条件成立,或者通知其他线程某个条件已经满足。条件变量通常与互斥锁(Mutex)一起使用,以确保线程安全。
条件变量:一种同步原语,允许线程等待某个条件成立,或者通知其他线程某个条件已经满足。
互斥锁(Mutex):用于保护共享资源,确保同一时间只有一个线程可以访问该资源。
条件变量通常有两种操作:
以下是一个简单的生产者-消费者问题的示例代码,使用C++标准库中的std::condition_variable
和std::mutex
:
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
std::queue<int> buffer;
std::mutex mtx;
std::condition_variable cv;
void producer(int id) {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::mutex> lock(mtx);
buffer.push(i);
std::cout << "Producer " << id << " produced "<< i << std::endl;
cv.notify_one(); // 通知消费者
}
}
void consumer(int id) {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !buffer.empty(); }); // 等待条件满足
int val = buffer.front();
buffer.pop();
std::cout << "Consumer " << id << " consumed " << val << std::endl;
}
}
int main() {
std::thread p1(producer, 1);
std::thread c1(consumer, 1);
p1.join();
c1.join();
return 0;
}
问题:线程在等待条件变量时可能会错过通知。
原因:如果线程在检查条件和进入等待状态之间,条件已经满足并且通知已经发出,那么该线程将错过通知并一直等待。
解决方法:
wait
调用中使用一个谓词函数,确保每次被唤醒后都重新检查条件。notify_all
:在某些情况下,使用notify_all
而不是notify_one
可以减少错过通知的概率,但会增加系统开销。cv.wait(lock, [] { return !buffer.empty(); }); // 使用谓词函数
通过这些方法,可以有效避免线程在等待条件变量时错过通知的问题。
领取专属 10元无门槛券
手把手带您无忧上云