Locking implementation

I am trying to understand how locks work.

Let's say I want to implement a really simple locking in C ++

class Resource{
    public:
    bool lock();
    void unlock();
    ... methods to change/read the Resource ...

    private:
    bool isLocked;
}

      

The resource user calls lock()

, and if isLocked

true, then lock()

returns false, and the resource user must either wait or do something else. If isLocked

false, it lock()

sets isLocked

to true and returns true. The caller can then do whatever he wants for the resource. It calls unlock()

on the resource afterwards to be set isLocked

to false.

However, what if two users of the resource call at lock()

exactly the same time? Does this happen rarely? I think more formally it has to do with the fact that the operation is lock()

"atomic", although I'm not quite sure what that means.

+3


source to share


3 answers


"Atomic" means the operation cannot be interrupted. That is, you can be sure that the semantics of this operation are the same regardless of the behavior of other threads / processes. You are correct that something in your call lock()

should probably be atomic. Most architectures provide some useful instructions with guaranteed atomic behavior - you can also find some libraries built on these operations to give you more flexibility at the higher level you program at.



+3


source


With old standard C ++, you cannot implement your own locking since the locking variable itself is in a data race.

C ++ 11 and C11 add atomic variables that you can use for exactly this purpose; for example in C ++:



#include <atomic>

std::atomic<bool> isLocked;

bool lock() { return !isLocked.exchange(true); }

void unlock() { isLocked = false; }

      

The key point here is atomic swap and the (implicit) atomic store, which generate special hardware instructions and always race-free, and which you cannot "fake" with regular variables.

+5


source


This is not uncommon. He named a race condition and is the cause of many (if not most) errors in multithreading code.

There is no concept of threads / atomicity etc. in the C ++ standard, 1 so you will need to use the synchronization primitives offered by your OS (or perhaps via Boost).


<sub> 1. This is no longer the case for C ++ 11.
+1


source







All Articles