Closed MHCooke closed 1 year ago
James produced this code example.
#include <iostream>
#include <string>
#include <condition_variable>
#include <thread>
#include <chrono>
#include <queue>
std::condition_variable cond;
std::mutex cond_m;
bool stop_waiting = false;
std::queue<int> queue;
// cosumer
void printer() {
// unique lock defaults to locked.
std::unique_lock<std::mutex> lk(cond_m);
for (int i = 0; i < 10; i++){
// lk must be locked, otherwise wait will result in undefined behaviour. wait unlocks it and sleeps the thread until it is woken. when woken, it checks the predicate to see if it should go back to sleep or move on. if it moves on, then it locks lk
cond.wait(lk, []{return queue.empty() == false;});
std::cerr << "Printing: " << queue.front() << "\n";
queue.pop();
// optional: in the case that more than just basic number crunching is to be done, you can manually unlock and lock
lk.unlock();
std::this_thread::sleep_for(std::chrono::seconds(2));
lk.lock();
}
}
// supplier
void signaler() {
for (int i = 0; i < 10; i++){
{
// you don't specifically have to use lock_guard, but it expires at the end of it's scope, so it makes for nice RAII
std::lock_guard<std::mutex> lk(cond_m);
queue.push(3+i);
std::cerr << "Adding: " << 3+i << "\n";
}
// notify is used to wake up threads that are wait()ing
cond.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
cond.notify_all();
}
int main() {
std::thread t1(printer), t2(signaler);
t1.join();
t2.join();
}
(updated 21/03/23 to include a little more examples for working with the locks)
I think the next step would be to implement this into a message class, which can be passed to the threaads
Done
As a daft engineer, I want to have a thread that sleeps until a message is available to be process. How do I do this?
Success Criteria: