If your question is: can I use freely switch between one type of mutex and another at random? Then the answer is no (unless all the bottom layers use the same implementation, such as pthread_mutex.)
However, if you have different groups of resources that you want to protect, any one group of resources can be protected with any one implementation. Actually, it can at times be better to use a semaphore (i.e. semaphore are useful to define a one lock for write, many locks for reads).
So, if you have 4 groups of resources you are managing, you may use:
- std::mutex,
- pthread_mutex,
- boost::mutex,
- semaphores.
What you cannot do is use the boost::mutex to access data protected by the semaphores and vice versa, or std::mutex to use things protected by pthread_mutex.
As a simple example, in terms of code, this means a getter and a setter would be done this way:
void set(int new_value)
{
guard lock(my_mutex);
m_value = new_value;
}
int get() const
{
guard lock(my_mutex);
return m_value;
}
The two functions use the same mutex (here my_mutex
) and obvious the mutex has one type.
Opposed to that, you could not do that:
void set(int new_value)
{
guard lock(this_mutex_here);
m_value = new_value;
}
int get() const
{
SafeGuard lock(that_mutex_there);
return m_value;
}
In this second example, you use two different mutexes and that won't work as expected because the lock in set()
won't block the lock in get()
and vice versa. So there is nothing safe about it (even if one of the guards is called SafeGuard.)
So the rule is, if you protect m_value
with a mutex named my_mutex
, any time you access m_value
you must lock the my_mytex
mutex. Which implementation you are using does not matter, as long as you are consistent in this way.