C++ 条件变量实现生产者-消费者问题:多线程同步与队列管理
以下是使用条件变量实现生产者-消费者问题的代码示例,展示了如何利用条件变量 not_full_cv 和 not_empty_cv 实现生产者和消费者线程之间的同步,并使用互斥锁 mtx 保证对共享队列的访问互斥。
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <cstdlib>
const int MAX_SIZE = 10;
const int INITIAL_SIZE = 8;
std::queue<int> products;
std::mutex mtx;
std::condition_variable not_full_cv;
std::condition_variable not_empty_cv;
void producer(int id) {
while (true) {
std::unique_lock<std::mutex> lk(mtx);
not_full_cv.wait(lk, []{ return products.size() < MAX_SIZE; });
int product = rand() % 100;
products.push(product);
std::cout << "Producer " << id << " produced product " << product << std::endl;
not_empty_cv.notify_all();
lk.unlock();
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
void consumer(int id) {
std::this_thread::sleep_for(std::chrono::seconds(5));
while (true) {
std::unique_lock<std::mutex> lk(mtx);
not_empty_cv.wait(lk, []{ return !products.empty(); });
int product = products.front();
products.pop();
std::cout << "Consumer " << id << " consumed product " << product << std::endl;
not_full_cv.notify_all();
lk.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
for (int i = 0; i < INITIAL_SIZE; ++i) {
int product = rand() % 100;
products.push(product);
std::cout << "Initial product " << product << std::endl;
}
std::thread p1(producer, 1), p2(producer, 2), p3(producer, 3);
std::thread c1(consumer, 1), c2(consumer, 2);
p1.join();
p2.join();
p3.join();
c1.join();
c2.join();
return 0;
}
该程序中,生产者和消费者线程使用了条件变量 not_full_cv 和 not_empty_cv 来进行同步,以避免生产者向满队列中添加商品或消费者从空队列中取出商品的情况发生。生产者线程每次等待 not_full_cv 条件变量满足(即队列未满)后,向队列中添加一个随机商品,并通知消费者线程 not_empty_cv 条件变量已满足(即队列非空)。消费者线程每次等待 not_empty_cv 条件变量满足(即队列非空)后,从队列中取出一个商品,并通知生产者线程 not_full_cv 条件变量已满足(即队列未满)。生产者和消费者线程使用互斥锁 mtx 来保证对队列的访问互斥。生产者线程每 3 秒生产一个商品,消费者线程每 1 秒消费一个商品。程序的初始队列中有 8 个随机商品。
原文地址: https://www.cveoy.top/t/topic/mZLj 著作权归作者所有。请勿转载和采集!