【问题标题】:Is std::mutex fair? [duplicate]std::mutex 公平吗? [复制]
【发布时间】:2013-07-08 13:14:50
【问题描述】:

正如问题所述,std::mutex 公平吗?即,如果线程 A 锁定了互斥体,然后 B 和 C 按此顺序对其调用 'lock()' ,它们会以相同的顺序获得互斥体上的锁还是未指定顺序?

documentation 根本没有解决这个问题。

【问题讨论】:

  • 如果文档没有解决这个问题,我猜这意味着它未指定。
  • 为了让它们保持有序:stackoverflow.com/questions/9046746/…
  • 这个open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf 可能是“文档”的更好来源
  • 感谢您的提示,但这是一份工作草案。
  • 你必须为发布的版本支付一大笔钱。公平是一个实现细节。您唯一可以真正指望的是,不提供任何公平性的实现不太可能长期存在。或者换一种说法,当你使用别人的代码时,你应该有一些的信心,相信他们做对了。如果您不为实现命名,我们无法帮助您对此感觉更好。

标签: c++ c++11 mutex


【解决方案1】:

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

实际上std::mutex 实现可能会使用他们平台提供的任何互斥锁实现,这很不公平,因为这通常更简单、更有效。在窗户上,例如互斥锁大多是公平的,但并非总是如此。一些实现,例如线程构建块提供了公平的特殊互斥锁,但这些互斥锁不是基于操作系统的原生互斥锁,并且通常作为自旋锁实现(有自己的警告)。

【讨论】:

    【解决方案2】:

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

    为了确保线程以他们要求的相同顺序获取互斥锁,我建议您查看std::condition_variablestd::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();
        }
    }
    

    此示例展示了如何在处理某些数据之前对其进行处理。

    【讨论】:

    • 我需要知道 std::mutex 是否公平,而不是如何进行公平锁。#
    • 回复在我帖子的顶部。我认为这不公平,因为它没有具体说明。这就是为什么我想给你一个让锁公平的方法......
    • 那么使用condition_variable 究竟如何让事情变得公平?
    • 至少,通过一些代码,你可以让它变得公平。 wait 方法解锁互斥锁并将线程放入等待条件的线程列表中,您可以进行公平锁定。这是一个包含两个示例的链接:stackoverflow.com/questions/14792016/…
    • 我不认为 CV 使它成为一个公平的互斥体。 CV.notify_one() 可以唤醒任何线程。也许您可以使用 FIFO(队列)数据结构实现您的 CV 版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2013-12-29
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2012-11-02
    相关资源
    最近更新 更多