idkts
idkts

Reputation: 33

C++ threads producer consumer

I need to implement a piggy bank simulation where clients can either deposit or withdraw money from. The clients should be represented as threads, and the piggy bank is an integer variable. I need to create two functions called producer and consumer, which should be able to deposit or withdraw an amount defined by a parameter. Restrictions are that the consumer should only withdraw if there is enough money in the piggy bank. If not, it should wait for the piggy bank to fill up.

The consumer and producer have to simultaneously access the piggy bank, and add or remove random amounts.

I'm having troubles with this. I'm new to both c++ and threads. I have looked at different consumer producer solutions, but I can't find anything that helps.

This is my code so far. I reckon the structure is correct, but

 #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;
 } 

I need some sort of condition, but I don't know how to use the conditional variable.

Upvotes: 2

Views: 2792

Answers (1)

Solomon Slow
Solomon Slow

Reputation: 27115

One problem you could run in to: Your code does nothing to guarantee that the consumer will be waiting in the sem.wait(lck) call before the producer calls sem.notify(). If the producer gets there first, then the notification will be lost, and the consumer will never wake up.

Also, You should always use a loop to wait on a condition variable, and it should always test the condition for which you are waiting.

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

The test ensures that the consumer won't wait for a notification that never will come if the producer got there first.

You could say if instead of while, but the loop is a good habit to learn. You will need it later when you write a multi-consumer program because in that case, one consumer could wake up and discover that another consumer woke up first and took the money (or the task, or whatever it is that they are consuming.)

Upvotes: 1

Related Questions