📅  最后修改于: 2023-12-03 14:56:15.816000             🧑  作者: Mango
生产者消费者问题是一个多线程同步的经典问题,它包含两类线程:生产者和消费者。生产者生成数据并放入缓冲区,而消费者从缓冲区取出数据并消费它们。缓冲区的大小是有限的,因此生产者必须等待消费者消费数据以便继续生成数据。同样地,消费者必须等待生产者生成数据以便消费数据。这就是一个典型的同步问题。
在C++中,我们通常使用互斥锁和条件变量来实现生产者消费者问题。互斥锁用于同步访问共享资源,条件变量用于线程之间的通信。下面是一个使用互斥锁和条件变量实现的生产者消费者问题的示例:
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
std::queue<int> data; // 缓冲区
std::mutex mutex; // 互斥锁
std::condition_variable cond; // 条件变量
void producer() {
int i = 1;
while (i <= 10) {
std::unique_lock<std::mutex> lock(mutex);
data.push(i); // 生产数据
std::cout << "Producer: produced " << i << std::endl;
i++;
lock.unlock(); // 解锁
cond.notify_one(); // 唤醒一个消费者
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 等待一段时间
}
}
void consumer() {
int data_value;
while (true) {
std::unique_lock<std::mutex> lock(mutex);
while (data.empty()) { // 等待直到有数据
cond.wait(lock);
}
data_value = data.front(); // 取出数据
data.pop();
std::cout << "Consumer: consumed " << data_value << std::endl;
lock.unlock(); // 解锁
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 等待一段时间
}
}
int main() {
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}
代码说明:
除了使用互斥锁和条件变量外,我们还可以使用信号量来实现生产者消费者问题。信号量是一种同步原语,它可以用来协调多个线程的活动。下面是一个使用信号量实现的生产者消费者问题的示例:
#include <iostream>
#include <queue>
#include <thread>
#include <semaphore.h>
std::queue<int> data; // 缓冲区
sem_t sem_empty; // 空信号量
sem_t sem_full; // 满信号量
std::mutex mutex; // 互斥锁
void producer() {
int i = 1;
while (i <= 10) {
sem_wait(&sem_empty); // 等待空信号量
std::unique_lock<std::mutex> lock(mutex);
data.push(i); // 生产数据
std::cout << "Producer: produced " << i << std::endl;
i++;
lock.unlock(); // 解锁
sem_post(&sem_full); // 发送满信号量
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 等待一段时间
}
}
void consumer() {
int data_value;
while (true) {
sem_wait(&sem_full); // 等待满信号量
std::unique_lock<std::mutex> lock(mutex);
data_value = data.front(); // 取出数据
data.pop();
std::cout << "Consumer: consumed " << data_value << std::endl;
lock.unlock(); // 解锁
sem_post(&sem_empty); // 发送空信号量
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 等待一段时间
}
}
int main() {
sem_init(&sem_empty, 0, 10); // 初始化空信号量
sem_init(&sem_full, 0, 0); // 初始化满信号量
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
sem_destroy(&sem_empty); // 销毁空信号量
sem_destroy(&sem_full); // 销毁满信号量
return 0;
}
代码说明:
生产者消费者问题是一个多线程同步的经典问题,需要借助互斥锁、条件变量或信号量等同步原语来实现。在实现过程中,需要考虑到缓冲区的大小、生产者和消费者之间的同步和互斥等问题。在C++中,使用std::mutex、std::condition_variable和sem_t等函数来实现同步和互斥操作。