Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leads a C++11 std::mutex lock the blocked thread into a passive wait state?

I have the following situation:

Two C++11 threads are working on a calculation and they are synchronized through a std::mutex.

Thread A locks the mutex until the data is ready for the operation Thread B executes. When the mutex is unlocked Thread B starts to work.

Thread B tries to lock the mutex and is blocked until it is unlocked by Thread A.

void ThreadA (std::mutex* mtx, char* data)
{
    mtx->lock();
    //do something useful with data
    mtx->unlock();
}

void ThreadB (std::mutex* mtx, char* data)
{
    mtx->lock(); //wait until Thread A is ready
    //do something useful with data
    //.....
}

It is asserted that Thread A can block the mutex first.

Now I am wondering if the mtx->lock() in Thread B waits active or passive. So is Thread B polling the mutex state and wasting processor time or is released passively by the sheduler when the mutex is unlocked.

In the different C++ references it is only mentioned that the thread is blocked, but not in which way.

Could it be, however, that the std::mutex implementation is hardly depended on the used plattform and OS?

like image 586
Tobias Off Avatar asked Feb 09 '23 21:02

Tobias Off


1 Answers

It's highly implementation defined, even for the same compiler and OS

for example,on VC++, in Visual Studio 2010, std::mutex was implemented with Win32 CRITICAL_SECTION. EnterCriticalSection(CRITICAL_SECTION*) has some nice feature: first it tries to lock the CRITICAL_SECTION by iterating on the lock again and again. after specified number of iteration, it makes a kernel-call which makes the thread go sleep, only to be awakened up again when the lock is released and the whole deal starts again. in this case , the mechanism polls the lock again and again before going to sleep, then the control switches to the kernel.

Visual Studio 2012 came with a different implementation. std::mutex was implemented with Win32 mutex. Win32 mutex shifts the control immediately to the kernel. there is no active polling done by the lock.

you can read about the implementation switch in the answer : std::mutex performance compared to win32 CRITICAL_SECTION

So, it is unspecified how the mutex acquires the lock. it is the best not to rely on such behaviour.

ps. do not lock the mutex manually, use std::lock_guard instead. also, you might want to use condition_variable for more-refined way of controlling your synchronization.

like image 164
David Haim Avatar answered Feb 12 '23 01:02

David Haim