Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;线程生产者消费者_C++_Multithreading_Producer Consumer - Fatal编程技术网

C++ C++;线程生产者消费者

C++ C++;线程生产者消费者,c++,multithreading,producer-consumer,C++,Multithreading,Producer Consumer,我需要实现一个存钱罐模拟,客户可以从中存款或取款。客户端应该表示为线程,而piggy bank是一个整数变量。我需要创建两个名为producer和consumer的函数,它们应该能够存入或提取由参数定义的金额。限制是,消费者只有在存钱罐中有足够的钱时才能取款。如果没有,它应该等待小猪存钱罐装满 消费者和生产者必须同时访问存钱罐,并添加或删除随机数量 我在这方面遇到了麻烦。我对C++和线程都是新手。我看过不同的消费者-生产者解决方案,但我找不到任何有帮助的 这是到目前为止我的代码。我认为结构是正确

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

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

我在这方面遇到了麻烦。我对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;
 } 
#包括
#包括
#包括
#包括
使用名称空间std;
int储液罐;
互斥锁;
条件变量sem;
bool available=false;
无效消费者(整数金额){
唯一锁定lck(mlock);
sem.wait(lck);
储蓄罐-=金额;
}
无效生产者(整数金额){
唯一锁定lck(mlock);
储蓄罐+=金额;
//可用=储液罐>50;
sem.notify_all();
}
int main(){
储液罐=0;
线程cons(使用者,rand()%50+1);
螺纹产品(生产商,兰德()%50+1);
prod.join();
cons.join();
返回0;
} 

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

您可能遇到的一个问题是:您的代码不能保证消费者在生产者调用
sem.notify()
之前在
sem.wait(lck)
调用中等待。如果制作人先到了那里,通知就会丢失,消费者也永远不会醒来

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

while ( piggybank < amount ) {
    sem.wait();
}
piggybank -= amount;
while(piggybank
该测试确保消费者不会等待一个通知,如果生产者先到了,通知就永远不会出现


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

您的问题是?使用
条件变量的重载。wait()
它接受一个谓词,该谓词表示当
piggybank
具有足够的值时,等待应该解除阻止。另外-只是一个风格注释:我不喜欢
条件变量的名称
sem
。这对我来说似乎有误导性,因为它不是一个信号量。你还应该知道,由于目前生产者线程只向piggybank添加一次随机值,如果该值小于消费者想要提取的随机值,消费者将永远等待piggybank获得足够的值。当开发者说“生产者/消费者”,他们通常谈论的是一种体系结构,在这种体系结构中,生产者将不同的对象或不同的值放入队列中,消费者移除这些对象/值并对其进行处理。将存款到银行账户的人称为“生产者”,将取款人称为“生产者”“消费者”的比喻有些超出了它通常的界限。事实上,你不能说
if
而不是
while
,因为等待被允许错误地返回。即使解除阻塞不是虚假的,使用者仍然需要检查是否向
储液罐添加了足够的数据以允许“提取”。另外,C++14的
条件变量
支持重载,其中待测试的条件可以传递给
等待()
function-循环由库函数处理,使客户端代码更干净。