Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why to pass mutex as a parameter to a function being called by a thread?

At some places I have seen people creating a thread pool and creating threads and executing a function with those threads. While calling that function boost::mutex is passed by reference. Why it is done so? I believe you can have a mutex declared in the called function itself or can be declared a class member or global. Can anyone please explain?

e.g.

   myclass::processData()
   {
         boost::threadpool::pool pool(2);
         boost::mutex mutex;

         for (int i =0; data<maxData; ++data)
             pool.schedule(boost::bind(&myClass::getData, boost_cref(*this), boost::ref(mutex)));
    }

Then,

    myClass::getData(boost::mutex& mutex)
    {
         boost::scoped_lock(mutex)    // Why can't we have class member variable mutex or                                     
                                      //local mutex here
        //Do somethign Here
}
like image 689
polapts Avatar asked Sep 26 '11 12:09

polapts


People also ask

Why do we need mutexes?

Mutex or Mutual Exclusion Object is used to give access to a resource to only one process at a time. The mutex object allows all the processes to use the same resource but at a time, only one process is allowed to use the resource. Mutex uses the lock-based technique to handle the critical section problem.

Why is mutex thread safe?

Shared mutexes and locks are an optimization for read-only pieces of multi-threaded code. It is totally safe for multiple threads to read the same variable, but std::mutex can not be locked by multiple threads simultaneously, even if those threads only want to read a value. Shared mutexes and locks allow this.

What is mutex in threading?

Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.

Does mutex block thread?

If the mutex is already locked by another thread, the subroutine blocks the calling thread until the mutex is unlocked. If the mutex is already locked by the calling thread, the subroutine might block forever or return an error depending on the type of mutex.


1 Answers

Mutex's are non-copyable objects, and while they can be members of a class, it would greatly complicate a parent class's copy-ability. Thus one preferred method, should a number of class instances need to share the same data, would be to create the mutex as a static data-member. Otherwise if the mutex only needed to be locked within an instance of the class itself, you could create a pointer to a mutex as a non-static data-member, and then each copy of the class would have it's own dynamically allocated mutex (and remain copyable if that is a requirement).

In the code example above, what's basically taking place is there is a global mutex being passed into the thread pool by reference. That enables all the threads sharing the same memory locations to create an exclusive lock on that memory using the exact same mutex, but without the overhead of having to manage the non-copyable aspect of the mutex itself. The mutex in this code example could have also been a static data-member of class myClass rather than a global mutex that is passed in by reference, the assumption being that each thread would need to lock some memory that is globally accessible from each thread.

The problem with a local mutex is that it's only a locally accessible version of the mutex ... therefore when a thread locks the mutex in order to share some globally accessible data, the data itself is not protected, since every other thread will have it's own local mutex that can be locked and unlocked. It defeats the whole point of mutual exclusion.

like image 146
Jason Avatar answered Sep 22 '22 12:09

Jason