I'm trying to understand how locks work.
Let's say I want to implement a really simple lock in C++
class Resource{
public:
bool lock();
void unlock();
... methods to change/read the Resource ...
private:
bool isLocked;
}
The user of the Resource calls lock()
, and if isLocked
is true, then lock()
returns false, and the user of the Resource has to either wait, or do something else. If isLocked
is false, then lock()
sets isLocked
to true, and returns true. Then the caller can do whatever he wants to the resource. He calls unlock()
on the resource afterwards to set isLocked
to false.
However, what if two users of the resource call lock()
at precisely the same time? Does this situation rarely happen? I think more formally, this involves making the lock()
operation "atomic", though I'm not precisely sure what that word means.
With the old, standard C++, you cannot implement your own lock, since the lock variable itself is in a data race.
C++11 and C11 add atomic variables, which you can use for precisely this purpose; e.g. in C++:
#include <atomic>
std::atomic<bool> isLocked;
bool lock() { return !isLocked.exchange(true); }
void unlock() { isLocked = false; }
The key here are the atomic exchange and the (implicit) atomic store, which generate special hardware instructions and are always race-free, and which you cannot "fake" with ordinary variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With