4

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?

Tobias Off
  • 73
  • 1
  • 8
  • 5
    If you want thread B to do some work once thread A perform some other work, you most definitely want a `std::condition_variable`. Also, avoid calling the `lock()` member functions directly in your code; prefer using a `std::unique_lock` or `std::lock_guard`. – bku_drytt Oct 05 '15 at 14:09
  • I know thats a standard way to do that. The metioned example is a rather syntetic one. The thing I want to know is the character of this waiting condition without digging me days through C++ standard papers. – Tobias Off Oct 05 '15 at 14:18
  • 1
    It will be whatever the implementors of your standard library thought was best on your platform. – David Schwartz Oct 05 '15 at 15:39

1 Answers1

8

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.

Community
  • 1
  • 1
David Haim
  • 25,446
  • 3
  • 44
  • 78
  • First thanks for your answer. That is what I was looking for. As I mentioned I know the thing with the lock guard, but I wanted to know how things work. Are there also some documents for unixoid Systems you know? – Tobias Off Oct 05 '15 at 15:55
  • I'm not familliar with other documents, sorry. but usually googling "how XXX works internally" gives great answers – David Haim Oct 06 '15 at 11:46
  • Ok, thanks a lot. Now I have at least some more keywords to search with and a trace to find more information. – Tobias Off Oct 06 '15 at 11:56