I have a single producer, single consumer use case where the consumer blocks until the producer has made new data available. Here are two synchronization approaches that implement this:
New C++20 approach using std:atomic<bool>::wait
data d;
std::atomic<bool> ready = false;
void consume_bool() {
ready.wait(false);
do_consume(d);
ready.store(false);
ready.notify_one();
}
void produce_bool() {
ready.wait(true);
d = do_produce();
ready.store(true);
ready.notify_one();
}
Traditional C++17 approach using std::condition_variable
data d;
std::mutex m;
std::condition_variable consume_ready, produce_ready;
bool ready = false;
void consume_cv() {
std::unique_lock lock{m};
consume_ready.wait(m, [] { return ready; });
do_consume(m);
ready.store(false);
produce_ready.notify_one();
}
void produce_cv() {
std::unique_lock lock{m};
produce_ready.wait(m, [] { return !ready; });
d = do_produce();
ready.store(true);
consume_ready.notify_one();
}
Question
To me, it seems like the C++20 approach has entirely obsoleted the old approach.
Is there a reason to still use traditional std::mutex and std::condition_variable synchronization?
Also, is waiting with std::atomic_bool as efficient (i.e. no busy-wait) as waiting for a std::condition_variable?
std::atomic_bool::waitis somehow inferior to waiting onstd::condition_variable, then that'd be a reason to use the old version, at least in some cases. It's a general question, but the point is to float ideas of what could be used to justify the old version in this particular example.