【问题标题】:C++ threads producer consumerC++线程生产者消费者
【发布时间】:2018-09-24 01:29:59
【问题描述】:

我需要实现一个存钱罐模拟,客户可以从中存款或取款。客户端应该表示为线程,而存钱罐是一个整数变量。我需要创建两个称为生产者和消费者的函数,它们应该能够存入或提取由参数定义的金额。限制是消费者只有在存钱罐中有足够的钱时才能取款。如果没有,它应该等待存钱罐填满。

消费者和生产者必须同时访问存钱罐,并添加或删除随机金额。

我在这方面遇到了麻烦。我是 C++ 和线程的新手。我查看了不同的消费者生产者解决方案,但找不到任何帮助。

到目前为止,这是我的代码。我认为结构是正确的,但是

 #include <iostream>
 #include <thread>
 #include <mutex>
 #include <condition_variable>

 using namespace std;

 int piggybank;
 mutex mlock;
 condition_variable sem;
 bool available = false;

 void consumer(int amount){
     unique_lock<mutex> lck(mlock);
     sem.wait(lck);
     piggybank -= amount;
 }

 void producer(int amount){
     unique_lock<mutex> lck(mlock);
     piggybank += amount;
     //available = piggybank > 50;
     sem.notify_all();
 }

 int main() {
     piggybank = 0;

     thread cons(consumer, rand()%50+1);
     thread prod(producer, rand()%50+1);

     prod.join();
     cons.join();

     return 0;
 } 

我需要某种条件,但我不知道如何使用条件变量。

【问题讨论】:

  • 你的问题是?
  • 使用condition_variable.wait() 的重载,它接受一个谓词,当piggybank 有足够的值时,等待应该解除阻塞。
  • 另外 - 只是一个风格评论:我不喜欢 sem 的名称 condition_variable。这对我来说似乎是一种误导,因为它不是信号量。
  • 您还应该知道,由于目前生产者线程只向存钱罐添加一个随机值,如果该数量小于消费者想要提取的随机数量,消费者将永远等待捎带获得足够的价值。
  • 当开发人员说“生产者/消费者”时,他们通常指的是生产者将不同对象不同值放入队列的架构,消费者删除对象/值并对它们做一些事情。将把钱存入银行账户的人称为“生产者”,将提款的人称为“消费者”,这种比喻有点超出了通常的界限。

标签: c++ multithreading producer-consumer


【解决方案1】:

您可能会遇到一个问题:您的代码无法保证消费者将在sem.wait(lck) 调用中等待生产者调用sem.notify()。如果生产者先到,则通知将丢失,消费者永远不会醒来。

此外,您应该始终使用循环来等待条件变量,并且它应该始终测试您正在等待的条件。

while ( piggybank < amount ) {
    sem.wait();
}
piggybank -= amount;

测试确保消费者不会等待如果生产者先到达那里就永远不会出现的通知。

您可以说if 而不是while,但循环是一个学习的好习惯。稍后在编写多消费者程序时将需要它,因为在这种情况下,一个消费者可能会醒来并发现另一个消费者首先醒来并拿走了钱(或任务,或他们正在消费的任何东西)。

【讨论】:

  • 实际上 - 你不能说 if 而不是 while 因为允许等待虚假返回。即使解锁不是虚假的,消费者仍需要检查是否有足够的添加到piggybank 以允许“提款”。
  • 附注:C++14 的 condition_variable 支持重载,其中要测试的条件可以传递给 wait() 函数 - 循环由库函数处理客户端代码更简洁。
猜你喜欢
  • 1970-01-01
  • 2017-02-01
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
相关资源
最近更新 更多