正如问题所述,std::mutex
公平吗?即,如果线程 A 锁定了互斥体,然后 B 和 C 按此顺序对其调用“lock()”,它们会以相同的顺序获得互斥体上的锁还是未指定顺序?
该文档根本没有解决这个问题。
该标准(第 30.4 节)没有提及任何关于互斥锁上竞争线程之间公平性的要求,因此它可能是公平的,也可能不是公平的。
在实践中std::mutex
,实现可能会使用他们平台提供的任何互斥实现,这很不公平,因为这通常更简单、更有效。在 Windows 上,例如互斥锁大多是公平的,但并非总是如此。一些实现,例如线程构建块提供了公平的特殊互斥锁,但这些不是基于操作系统的本地互斥锁,并且通常实现为自旋锁(它们有自己的警告)。
如果文档没有解决它,我们可能会建议未指定,如果未指定,您可能会惊讶地发现他们以他们要求的相同顺序获得锁......
为了确保线程以他们要求的相同顺序获取互斥锁,我建议你看一下std::condition_variable
或 at 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();
}
}
这个例子展示了如何在处理某些数据之前对其进行处理。