I'd like to learn more about multithreading programming, and I thought that it would be a good exercise to try to implement some of the C# synchronization primitives in C++.
I've started with ManualResetEvent, and this is what I have so far:
class manual_reset_event
{
public:
void wait_one()
{
if (cv_flag_.load() == false)
{
thread_local std::mutex mutex;
std::unique_lock<std::mutex> lock(mutex);
cond_var_.wait(lock, [this]() { return cv_flag_.load(); });
}
}
void set()
{
cv_flag_.store(true);
}
void reset()
{
cv_flag_.store(false);
}
private:
std::condition_variable cond_var_;
std::atomic<bool> cv_flag_;
};
However, there is a race condition here: you could call wait_one() on one thread, pass the if (cv_flag) check, and then call set from another thread. This will cause wait_one() to wait, even though cv_flag_ is now true.
I could solve this by using a lock on wait_one, set and reset.
I think I could also solve this by calling cond_var_.notify_all() immediately after cond_var_.wait() on wait_one(), but I don't think this is a great idea (although maybe I'm wrong).
I was wondering if there is something else (maybe even a completely different approach without using conditional_variables) that I can do here to avoid this race condition.
Thank you very much!
Aucun commentaire:
Enregistrer un commentaire