C++11中的condition_variable
在C++11中,条件变量(std::condition_variable
)是线程同步机制之一,用于在多线程环境中实现线程间的通信和协调。它允许一个或多个线程在某个条件尚未满足时等待,直到其他线程通知条件已经满足。条件变量通常与互斥锁(std::mutex
)一起使用,以确保线程安全。
1. 包含头文件
在使用条件变量之前,需要包含 <condition_variable>
和 <mutex>
头文件:
#include <condition_variable>
#include <mutex>
2. 声明条件变量和互斥锁
条件变量需要与互斥锁配合使用,互斥锁用于保护共享资源,条件变量用于线程间的同步。
std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量
3. 等待条件
线程可以通过 cv.wait()
或 cv.wait_for()
等方法等待条件满足。cv.wait()
需要一个互斥锁作为参数,并且会自动释放互斥锁,直到条件变量被通知为止。在等待期间,线程会被阻塞。
std::unique_lock<std::mutex> lock(mtx); // 加锁
cv.wait(lock,[](){return condition; };);// 等待条件满足
condition
是一个布尔表达式,用于判断是否满足等待条件。std::unique_lock
是一种更灵活的互斥锁,支持延迟加锁和解锁。
4. 通知条件
当条件满足时,可以通过 cv.notify_one()
或 cv.notify_all()
唤醒等待的线程:
cv.notify_one()
:唤醒一个等待的线程。cv.notify_all()
:唤醒所有等待的线程。
示例代码
以下是一个完整的示例,展示了如何使用条件变量实现生产者-消费者模型:
#include <iostream>
#include<mutex>
#include<condition_variable>
#include<thread>
#include<queue>
using namespace std;std::queue<int> que; // 共享队列
std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量// 生产者线程
void Producer()
{for (int i = 0; i < 10; i++){std::unique_lock<std::mutex> lock(mtx); // 加锁que.push(i); // 生产数据cout << "Producer " << i << endl;lock.unlock();cv.notify_one(); // 通知消费者std:this_thread::sleep_for(std::chrono::milliseconds(100));}
}// 消费者线程
void Customer()
{while (true){std::unique_lock<std::mutex> lock(mtx); // 加锁cv.wait(lock, []() {return !que.empty(); }); // 等待队列非空int nValue = que.front(); // 消费数据que.pop();std::cout << "customer " << nValue << endl;if (nValue == 9)break;lock.unlock();std:this_thread::sleep_for(std::chrono::milliseconds(100));}
}int main()
{std::thread th1(Producer);std::thread th2(Customer);th1.join();th2.join();std::cout << "Hello World!\n";
}
代码运行结果:
注意事项
- 条件变量必须与互斥锁配合使用,否则会导致未定义行为。
- 虚假唤醒:
cv.wait()
可能会因为虚假唤醒而被触发,因此需要在等待条件中使用循环或条件表达式来确保条件真正满足。 - 线程安全:在使用条件变量时,必须确保共享资源的访问是线程安全的,通常通过互斥锁来保护共享资源。
通过合理使用条件变量,可以实现高效的线程同步和通信,适用于生产者-消费者、线程池等多种场景。
说明:以上代码来自kimi AI助手。