Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost, mutex concept

I am new to multi-threading programming, and confused about how Mutex works. In the Boost::Thread manual, it states:

Mutexes guarantee that only one thread can lock a given mutex. If a code section is surrounded by a mutex locking and unlocking, it's guaranteed that only a thread at a time executes that section of code. When that thread unlocks the mutex, other threads can enter to that code region:

My understanding is that Mutex is used to protect a section of code from being executed by multiple threads at the same time, NOT protect the memory address of a variable. It's hard for me to grasp the concept, what happen if I have 2 different functions trying to write to the same memory address.

Is there something like this in Boost library:

  1. lock a memory address of a variable, e.g., double x, lock (x); So that other threads with a different function can not write to x.
  2. do something with x, e.g., x = x + rand();
  3. unlock (x)

Thanks.

like image 564
2607 Avatar asked Feb 16 '12 21:02

2607


2 Answers

The mutex itself only ensures that only one thread of execution can lock the mutex at any given time. It's up to you to ensure that modification of the associated variable happens only while the mutex is locked.

C++ does give you a way to do that a little more easily than in something like C. In C, it's pretty much up to you to write the code correctly, ensuring that anywhere you modify the variable, you first lock the mutex (and, of course, unlock it when you're done).

In C++, it's pretty easy to encapsulate it all into a class with some operator overloading:

class protected_int {
    int value; // this is the value we're going to share between threads
    mutex m;
public:
    operator int() { return value; } // we'll assume no lock needed to read
    protected_int &operator=(int new_value) {
        lock(m);
        value = new_value;
        unlock(m);
        return *this;
    }
};

Obviously I'm simplifying that a lot (to the point that it's probably useless as it stands), but hopefully you get the idea, which is that most of the code just treats the protected_int object as if it were a normal variable.

When you do that, however, the mutex is automatically locked every time you assign a value to it, and unlocked immediately thereafter. Of course, that's pretty much the simplest possible case -- in many cases, you need to do something like lock the mutex, modify two (or more) variables in unison, then unlock. Regardless of the complexity, however, the idea remains that you centralize all the code that does the modification in one place, so you don't have to worry about locking the mutex in the rest of the code. Where you do have two or more variables together like that, you generally will have to lock the mutex to read, not just to write -- otherwise you can easily get an incorrect value where one of the variables has been modified but the other hasn't.

like image 187
Jerry Coffin Avatar answered Sep 30 '22 00:09

Jerry Coffin


No, there is nothing in boost(or elsewhere) that will lock memory like that. You have to protect the code that access the memory you want protected.

what happen if I have 2 different functions trying to write to the same memory address.

Assuming you mean 2 functions executing in different threads, both functions should lock the same mutex, so only one of the threads can write to the variable at a given time.

Any other code that accesses (either reads or writes) the same variable will also have to lock the same mutex, failure to do so will result in indeterministic behavior.

like image 20
nos Avatar answered Sep 30 '22 00:09

nos