I have a consumer thread that must read from a buffer without locking. It is fine if the operation must be skipped because a producer thread is writing to the buffer. So, the most appropriate choice seems to me to be an atomic TestAndSet on some flag.
Now, those aforementioned producer threads must respect this flag as well, because they can't start writing to the buffer while the consumer is reading from it. I could solve this using atomic_flag::test_and_set like the following code:
while (flag.test_and_set())
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
...but writing my own spin lock seems less than ideal. I would rather have my thread sleep until it is woken as a result of the flag being cleared. Something like:
flag.enter();
TLDR: How best to synchronize two threads where one can lock and the other can't?
Use a std::mutex
.
The readers can use try_lock
to avoid blocking.
The writers (producers) can use the blocking lock
function as usual.
Of course, to avoid leaking a lock, use std::unique_lock
. Readers should pass std::try_to_lock
as the second argument. You should then check owns_lock()
to see whether the data can be safely read or a write was in progress.