5

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.

asked Apr 7, 2012 at 22:03

3 Answers 3

7

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.

answered Apr 7, 2012 at 22:15
Sign up to request clarification or add additional context in comments.

Comments

3

"Atomic" means that the operation can't be interrupted. That is, you can be sure that the semantics of that operation are the same regardless of the behaviour of other threads/processes. You're right that something in your lock() call will likely have to be atomic. Most architectures provide some helpful instructions with guaranteed atomic behaviour - you might also find some libraries built on those operations to give you more flexibility at the higher layer you're programming at.

answered Apr 7, 2012 at 22:06

2 Comments

Would atomicity be a characteristic of the lock() method as a whole, or particular statements in the lock() method? The first option seems easier to work with.
Well that's really up to your implementation, I guess. At the really fundamental level, it's only single machine instructions that are atomic. You can extend that up through other layers by writing appropriate code, though.
1

It's not at all rare. It's called a race condition, and is the cause of many (if not most) bugs in multithreaded code.

The C++ standard doesn't really have any concept of threads/atomicity and so on,1 so you'll need to rely on synchronisation primitives offered by your OS (or perhaps via Boost).


1. This is no longer true with C++11.

answered Apr 7, 2012 at 22:06

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.