I am trying to teach myself multithreading and I followed this tutorial here: https://www.classes.cs.uchicago.edu/archive/2013/spring/12300-1/labs/lab6/
If you scroll all the way to the bottom there is a sample snippet of a producer-consumer and it asks us to solve the race conditions found in this code:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
#include <queue>
using namespace std;
int main() {
int c = 0;
bool done = false;
queue<int> goods;
thread producer([&]() {
for (int i = 0; i < 500; ++i) {
goods.push(i);
c++;
}
done = true;
});
thread consumer([&]() {
while (!done) {
while (!goods.empty()) {
goods.pop();
c--;
}
}
});
producer.join();
consumer.join();
cout << "Net: " << c << endl;
}
The Net value at the end should be 0, here is my attempt at it:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
#include <queue>
#include <atomic>
using namespace std;
int main() {
int c = 0;
bool done = false;
queue<int> goods;
mutex mtx;
condition_variable cond_var;
// thread to produce 500 elements
thread producer([&]() {
for (int i = 0; i < 500; ++i) {
// lock critical secion
unique_lock<mutex> lock(mtx);
goods.push(i);
c++;
lock.unlock();
// notify consumer that data has been produced
cond_var.notify_one();
}
// notify the consumer that it is done
done = true;
cond_var.notify_one();
});
// thread to consume all elements
thread consumer([&]() {
while (!done) {
unique_lock<mutex> lock(mtx);
while (!goods.empty()) {
goods.pop();
c--;
}
// unlocks lock and wait until something in producer gets put
cond_var.wait(lock);
}
});
producer.join();
consumer.join();
cout << "Net: " << c << endl;
}
I feel like I am fundamentally missing something. I believe the biggest problem I am having is in the consumer with the cond_var.wait() because if the producer sets "done" to true then the consumer won't go back into the while(!goods.empty()). I am not sure how to fix it though.
Any hints, explanations or even different approaches would be appreciated!
Aucun commentaire:
Enregistrer un commentaire