C++ 使用条件变量实现生产者和消费者模式

背景

在 C++ 中使用一个可调用对象构造一个 std::thread 对象,即可创建一个线程;使用互斥量 std::mutex 来确保多个线程对共享数据的读写操作的同步问题;使用 std::condition_variable 来解决线程执行顺序的同步问题。

生产者和消费者模式

在 C++ 中可以使用 std::condition_variable 来实现生产者和消费者模式:生产者在缓冲区未满时不断添加数据,并唤醒消费者进行数据读取;消费者在缓存区为空时阻塞等待生产者的唤醒,并在读取数据后唤醒等待的生产者可以继续添加数据。
在这里插入图片描述

代码示例

#include "thread"
#include "iostream"
#include "queue"
#include "condition_variable"
#include <mutex>using namespace std;
class ProducerAndConsumerDemo
{
public:
  void producerNumber();//生产数据
  void consumerNumber();//消费数据
private:
  const int dataSize = 1000;//总数据量
  queue<int> listBuffer;//数据缓存区
  const int bufferSize = 10;//缓存区大小
  condition_variable bufferNotEmpty;//信号量--缓存区有数据了
  condition_variable bufferNotFull;//信号量--缓存区不满了
  mutex m_mutex;//互斥量
};
void ProducerAndConsumerDemo::producerNumber()
{
  for (int i = 0; i < dataSize; ++i)
  {
    {
      unique_lock<mutex> locker(m_mutex);
      bufferNotFull.wait(locker, [&]() { return listBuffer.size() < bufferSize; });//缓存区满了则阻塞
      listBuffer.push(i);
      cout << "生产者---生产了数字:" << i << ",当前 bufferSize:" << listBuffer.size() << endl;
    }//解锁互斥量
    bufferNotEmpty.notify_one();
    this_thread::sleep_for(chrono::milliseconds(1000));//模拟生产耗时
  }
}
void ProducerAndConsumerDemo::consumerNumber()
{
  while (true)
  {
    {
      unique_lock<mutex> locker(m_mutex);
      bufferNotEmpty.wait(locker, [&]() {return listBuffer.size() > 0; });//缓冲区为空则阻塞
      int i = listBuffer.front(); listBuffer.pop();
      cout << "消费者---消费了数字:" << i << ",当前 bufferSize:" << listBuffer.size() << endl;
    }//解锁互斥量
    bufferNotFull.notify_one();
    this_thread::sleep_for(chrono::milliseconds(2000));//模拟消费耗时
  }
}int main()
{
  ProducerAndConsumerDemo pcDemo;
  thread consumerThread(&ProducerAndConsumerDemo::producerNumber,&pcDemo);
  thread producerThread(&ProducerAndConsumerDemo::consumerNumber, &pcDemo);
  
  producerThread.join();
  consumerThread.join();system("pause");
    return 0;
}

执行结果如下:
在这里插入图片描述

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是使用条件变量实现生产者-消费者模型的示例代码,假设有一个缓冲区可以放置整数: ```c #include <pthread.h> #include <stdio.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; // 缓冲区 int count = 0; // 缓冲区中整数的数量 pthread_mutex_t mutex; // 互斥锁 pthread_cond_t producer_cond, consumer_cond; // 条件变量 void *producer(void *arg) { int i; for (i = 0; i < 100; i++) { pthread_mutex_lock(&mutex); while (count == BUFFER_SIZE) { // 缓冲区已满,等待消费者消费 pthread_cond_wait(&producer_cond, &mutex); } buffer[count] = i; count++; printf("Produced: %d\n", i); pthread_cond_signal(&consumer_cond); // 唤醒一个消费者线程 pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } void *consumer(void *arg) { int i; while (1) { pthread_mutex_lock(&mutex); while (count == 0) { // 缓冲区已空,等待生产者生产 pthread_cond_wait(&consumer_cond, &mutex); } i = buffer[count - 1]; count--; printf("Consumed: %d\n", i); pthread_cond_signal(&producer_cond); // 唤醒一个生产者线程 pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } int main() { pthread_t producer_thread, consumer_thread; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&producer_cond, NULL); pthread_cond_init(&consumer_cond, NULL); pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&producer_cond); pthread_cond_destroy(&consumer_cond); return 0; } ``` 上述代码中,生产者线程负责向缓冲区中生产整数,消费者线程负责从缓冲区中消费整数。生产者消费者之间通过互斥锁和条件变量进行同步和通信。其中,生产者线程在缓冲区已满时等待消费者消费,消费者线程在缓冲区已空时等待生产者生产。当生产者向缓冲区中生产了一个整数时,唤醒一个消费者线程;当消费者从缓冲区中消费了一个整数时,唤醒一个生产者线程。这样就能够保证生产者消费者之间的同步和通信。 ### 回答2: 示例代码如下: #include <pthread.h> #include <stdio.h> #include <unistd.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int count = 0; int in = 0; int out = 0; pthread_mutex_t mutex; pthread_cond_t cond_var_producer; pthread_cond_t cond_var_consumer; void *producer(void *arg) { int i; for (i = 0; i < 20; i++) { pthread_mutex_lock(&mutex); if (count == BUFFER_SIZE) { pthread_cond_wait(&cond_var_producer, &mutex); } buffer[in] = i; in = (in + 1) % BUFFER_SIZE; count++; printf("Producer produced item %d\n", i); pthread_cond_signal(&cond_var_consumer); pthread_mutex_unlock(&mutex); usleep(100000); } pthread_exit(NULL); } void *consumer(void *arg) { int i; for (i = 0; i < 20; i++) { pthread_mutex_lock(&mutex); if (count == 0) { pthread_cond_wait(&cond_var_consumer, &mutex); } int item = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; printf("Consumer consumed item %d\n", item); pthread_cond_signal(&cond_var_producer); pthread_mutex_unlock(&mutex); usleep(100000); } pthread_exit(NULL); } int main() { pthread_t producer_thread, consumer_thread; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond_var_producer, NULL); pthread_cond_init(&cond_var_consumer, NULL); pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond_var_producer); pthread_cond_destroy(&cond_var_consumer); return 0; } 以上代码使用条件变量和互斥锁来实现生产者-消费者的模型。生产者在缓冲区满时会等待消费者消耗一个产品后才能继续生产,消费者在缓冲区空时会等待生产者生产一个产品后才能继续消费。 ### 回答3: 生产者-消费者问题是一个经典的并发编程问题,可以通过条件变量来解决。条件变量是用于线程间通信的一种机制,它通过一个线程通知另外一个线程某个条件发生或者不发生,以便让另外一个线程做出相应的处理。 在C语言中,可以使用pthread库来实现条件变量。下面是一个生产者-消费者的代码示例: ```c #include <stdio.h> #include <pthread.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥量 pthread_cond_t count_cond = PTHREAD_COND_INITIALIZER; // 条件变量 void* producer(void* arg) { for (int i = 0; i < 20; i++) { pthread_mutex_lock(&mutex); // 如果缓冲区已满,则等待消费者消费产品 while (count == BUFFER_SIZE) { pthread_cond_wait(&count_cond, &mutex); } buffer[count++] = i; printf("Producer: produce item %d\n", i); // 通知消费者有新产品可以消费 pthread_cond_signal(&count_cond); pthread_mutex_unlock(&mutex); } return NULL; } void* consumer(void* arg) { for (int i = 0; i < 20; i++) { pthread_mutex_lock(&mutex); // 如果缓冲区为空,则等待生产者生产产品 while (count == 0) { pthread_cond_wait(&count_cond, &mutex); } int item = buffer[--count]; printf("Consumer: consume item %d\n", item); // 通知生产者有空位可以继续生产 pthread_cond_signal(&count_cond); pthread_mutex_unlock(&mutex); } return NULL; } int main() { pthread_t producer_thread, consumer_thread; pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); return 0; } ``` 上述代码中,生产者线程不断向缓冲区中生产物品,而消费者线程不断从缓冲区中消费物品。当缓冲区已满时,生产者线程会阻塞并等待消费者线程消费物品,而当缓冲区为空时,消费者线程会阻塞并等待生产者线程生产物品。生产者线程通过条件变量`count_cond`向消费者线程发送通知,消费者线程通过条件变量`count_cond`向生产者线程发送通知,从而实现线程间的同步与通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值