Suppose there is a simple buffer which serves as the transfer point for some data between a producer and consumer thread. From reading around I have put together the following:
const std::chrono::time_point<std::chrono::steady_clock> TIMEOUT;
std::condition_variable waitForData;
std::mutex hasDataMutex;
std::atomic<bool> hasData;
void blocking_read(){
std::unique_lock<std::mutex> lock(hasDataMutex);
if (!hasData) {
waitForData.wait_until(lock, TIMEOUT,
[&]() -> bool { return hasData; });
}
}
void put_data(char* buf) {
//...write data into local buffer
std::unique_lock<std::mutex> lock(hasDataMutex);
hasData = true;
waitForData.notify_one();
}
Assuming the variables were properly initialized: is it necessary, or in the reverse, superfluous to have hasData
declared atomic
? Or is it even possible to get away without the mutex if I use atomic
?
Is there a freely available "Multithreading in C++" write-up somewhere that you would recommend?
Using both atomic
and mutex
is overkill here. Worth noting that there are situations where it's useful, like Singleton double-checked locking.
If you have C++20, you can use atomic::wait()
instead of mutex
and conditional_variable
.