4

As the question states, is std::mutex fair? i.e., if thread A locked the mutex and then B and C call 'lock()' on it in this order, will they obtain the lock on the mutex in this same order or is the order unspecified?

The documentation doesn't address this at all.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
mort
  • 12,988
  • 14
  • 52
  • 97
  • 6
    If the documentation doesn't address it, I'm going to guess that means it's unspecified. – Gabe Jul 08 '13 at 13:17
  • 2
    In order to keep them in order: http://stackoverflow.com/questions/9046746/do-mutex-locks-happen-in-the-same-order-they-are-asked – fatihk Jul 08 '13 at 13:30
  • 1
    This http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf might be a better source for "the documentation" – doctorlove Jul 08 '13 at 13:36
  • Thanks for the hint, but this is a working draft. – mort Jul 08 '13 at 13:48
  • You'll have to pay a good chunk of money for the released version. Fairness is an implementation detail. The only thing you can really count on is that an implementation that doesn't provide *any* fairness is unlikely to survive for long. Or to put it another way, when you use somebody else's code then you ought to have *some* confidence that they got it right. We can't help you feel better about this if you don't name the implementation. – Hans Passant Jul 08 '13 at 14:03
  • I don't know... my reading of the Standard suggests that it *is* fair. – John Dibling Jul 08 '13 at 14:11

2 Answers2

8

The standard (§30.4) does not mention anything about requirements regarding fairness between contending threads on a mutex, so it might be or might not be fair.

In practice std::mutex implementations will probably use whatever mutex implementation their platform provides, which are moslty unfair, as this is usually simpler and more efficient. On windows e.g. mutexes are mostly fair, but not always. Some implementations e.g. Thread Building Block provide special mutexes that are fair, but these are not based on the OSes native mutexes, and are usually implemented as spin-locks (which have their own caveats).

ronag
  • 49,529
  • 25
  • 126
  • 221
1

If the documentation does not address it, We could suggest that is unspecified and if it is not specified, you may have some surprise gessing that they obtain the lock in the same order they ask...

In order to be sure that the threads obtain the mutex in the same order they ask, I suggest you to take a look at std::condition_variable or at std::condition_variable_any.

They are both declared in <condition_variable> library header. In both cases, they need to work with a mutex in order to provide appropriate synchronization.

Here is a little example of how you can use it :

#include <mutex>
#include <condition_variable>

std::mutex mut;
std::queue<dummyData> data;
std::condition_variable cond;

void dummyDataPrepare()
{
    while( more_data_in_preparation() )
    {
        std::lock_guard<std::mutex> lo( mut );
        // doing many things on data
        cond.notify_one();
    }
}

void dummyDataProcessingThread()
{
    while( true )
    {
        std::unique_lock<std::mutex> lo( mut );
        cond.wait( lo,
            []{ return !data.empty(); });
        // Do whatever you want ...
        lo.unlock();
    }
}

This example shows how you can wait for some data to process before doing something on it.

Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62
  • I need to know if std::mutex is fair, not how to make a fair lock.# – mort Jul 08 '13 at 14:05
  • 1
    The reponse is at the top of my post. I suggest that it's not fair, because it is not specified. That why I wanted to give you a way to make a lock fair... – Pierre Fourgeaud Jul 08 '13 at 14:06
  • 2
    And how exactly does using `condition_variable` make things fair? – ronag Jul 08 '13 at 14:12
  • At least, with some code, you can make it fair. The fact that the `wait` methods unlock the mutex and put the thread in the list of threads waiting for the condition, you can make a fair lock. Here is a link with two examples doing this : http://stackoverflow.com/questions/14792016/creating-a-lock-that-preserves-the-order-of-locking-attempts-in-c11 – Pierre Fourgeaud Jul 08 '13 at 14:30
  • I don't think CV makes it a fair mutex. CV.notify_one() can wake any thread. May be you can implement your version of CV with FIFO (queue) data structure. – Shriganesh Shintre Aug 14 '18 at 01:16