BackSpace7777777
BackSpace7777777

Reputation: 161

What does std::mutex prevent threads from modifying?

What part of memory gets locked by mutex when .lock() or .try_lock(), is it just the function or is it the whole program that gets locked?

Upvotes: 2

Views: 1621

Answers (4)

uliwitness
uliwitness

Reputation: 8783

A mutex doesn't lock anything. You just use a mutex to communicate to other parts of your code that they should consider whatever you decide needs to be protected from access by several threads at the same time to be off-limits for now.

You could think of a mutex as something like a boolean okToModify. Whenever you want to edit something, you check if okToModify is true. If it is, you set it to false (preventing any other threads from modifying it), change it, then set okToModify back to true to tell the other threads you're done and give them a chance to modify:

// WARNING! This code doesn't actually work as a lock!
//    it is just an example of the concept.
struct LockedInt {
    bool okToModify; // This would be your mutex instead of a bool.
    int integer;
};

struct LockedInt myLockedInt = { true, 0 };    

...

while (myLockedInt.okToModify == false)
    ; // wait doing nothing until whoever is modifying the int is done.
myLockedInt.okToModify = false; // Prevent other threads from getting out of while loop above.
myLockedInt.integer += 1;
myLockedInt.okToModify = true; // Now other threads get out of the while loop if they were waiting and can modify.

The while loop and okToModify = false above is basically what locking a mutex does, and okToModify = true is what unlocking a mutex does.

Now, why do we need mutexes and don't use booleans? Because a thread could be running at the same time as those three lines above. The code for locking a mutex actually guarantees that the waiting for okToModify to become true and setting okToModify = false happen in one go, and therefore no other thread can get "in between the lines", for example by using a special machine-code instruction called "compare-and-exchange".

So do not use booleans instead of mutexes, but you can think of a mutex as a special, thread-safe boolean.

Upvotes: 1

Solomon Slow
Solomon Slow

Reputation: 27115

m.lock() doesn't really lock anything. What it does is, it waits to take ownership of the mutex. A mutex always either is owned by exactly one thread or else it is available. m.lock() waits until the mutex becomes available, and then it takes ownership of it in the name of the calling thread.

m.unlock releases the mutex (i.e., it relinquishes ownership), causing the mutex to once again become available.


Mutexes also perform another very important function. In modern C++, when some thread T performs a sequence of assignments of various values to various memory locations, the system makes no guarantees about when other threads U, V, and W will see those assignments, whether the other threads will see the assignments happen in the same order in which thread T performed them, or even, whether the other threads will ever see the assignments.

There are some quite complicated rules governing things that a programmer can do to ensure that different threads see a consistent view of shared memory objects (Google "C++ memory model"), but here's one simple rule:

Whatever thread T did before it releases some mutex M is guaranteed to be visible to any other thread U after thread U subsequently locks the same mutex M.

Upvotes: 0

NathanOliver
NathanOliver

Reputation: 180500

A mutex doesn't really lock anything, except for itself. You can think of a mutex as being a gate where you can only unlock it from the inside. When the gate is locked, any thread that tries to lock the mutex will sit there at the gate and wait for the current thread that is behind the gate to unlock it and let them in. When they gate is not locked then when you call lock you can just go in, close and lock the gate, and now no threads can get past the gate until you unlock it and let them in.

Upvotes: 4

OmnipotentEntity
OmnipotentEntity

Reputation: 17131

Nothing is locked except the mutex. Everything else continues running (until it tries to lock an already locked mutex that is). The mutex is only there so that two threads cannot run the code between a mutex lock and a mutex unlock at the same time.

Upvotes: 5

Related Questions