std::mutex 公平吗? [重复]

问题描述 投票:0回答:2

正如问题所述,

std::mutex
公平吗?即,如果线程 A 锁定了互斥锁,然后 B 和 C 按此顺序对其调用“lock()”,那么它们是否会以相同的顺序获得互斥锁,还是未指定顺序?

文档根本没有解决这个问题。

c++ c++11 mutex
2个回答
8
投票

该标准(第 30.4 节)没有提及有关互斥体上竞争线程之间公平性的任何要求,因此它可能公平也可能不公平。

在实践中,

std::mutex
实现可能会使用其平台提供的任何互斥实现,这大多是不公平的,因为这通常更简单、更高效。在 Windows 上,例如互斥体大多是公平的,但并非总是如此。一些实现例如线程构建块提供了公平的特殊互斥体,但这些互斥体不是基于操作系统本机互斥体,并且通常作为自旋锁实现(有其自己的注意事项)。


1
投票

如果文档没有解决这个问题,我们可以建议未指定,如果未指定,您可能会惊讶地猜测他们按照他们要求的顺序获得锁......

为了确保线程按照它们要求的顺序获取互斥锁,我建议您查看

std::condition_variable
std::condition_variable_any

它们都在

<condition_variable>
库头中声明。在这两种情况下,它们都需要使用互斥锁来提供适当的同步。

这是一个如何使用它的小例子:

#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();
    }
}

此示例展示了如何等待某些数据处理完毕后再对其执行操作。

© www.soinside.com 2019 - 2024. All rights reserved.