c++ - 为什么 std::mutex 需要很长时间才能共享?

标签 c++ pthreads std mutex stdmutex

这段代码演示了互斥锁在两个线程之间共享,但一个线程几乎一直拥有它。

#include <thread>
#include <mutex>
#include <iostream>

#include <unistd.h>

int main ()
{
    std::mutex m;

    std::thread t ([&] ()
    {
        while (true)
        {
            {
                std::lock_guard <std::mutex> thread_lock (m);

                sleep (1); // or whatever
            }
            std::cerr << "#";
            std::cerr.flush ();
        }
    });

    while (true)
    {
        std::lock_guard <std::mutex> main_lock (m);
        std::cerr << ".";
        std::cerr.flush ();
    }
}

在 Ubuntu 18.04 4.15.0-23-generic 上使用 g++ 7.3.0 编译。

输出是 #. 字符的混合,表明正在共享互斥量,但模式令人惊讶。通常是这样的:

.......#####..........................##################......................##

thread_lock 将互斥量锁定 的时间。几秒甚至几十秒后,main_lock 接收到控制权(短暂地),然后 thread_lock 取回控制权并保留很长时间。调用 std::this_thread::yield() 不会改变任何东西。

为什么两个互斥锁获得锁的可能性不同,我怎样才能使互斥锁以平衡的方式共享?

最佳答案

std::mutex 的设计并不公平。它并不能保证锁定的顺序保持不变,你要么幸运地获得锁,要么没有。

如果您想要更公平,请考虑使用 std::condition_variable like so :

#include <thread>
#include <mutex>
#include <iostream>
#include <condition_variable>

#include <unistd.h>

int main ()
{
    std::mutex m;
    std::condition_variable cv;
    std::thread t ([&] ()
    {
        while (true)
        {
            std::unique_lock<std::mutex> lk(m);
            std::cerr << "#";
            std::cerr.flush ();
            cv.notify_one();
            cv.wait(lk);
        }
    });

    while (true)
    {
        std::unique_lock<std::mutex> lk(m);
        std::cerr << ".";
        std::cerr.flush ();
        cv.notify_one();
        cv.wait(lk);
    }
}

关于c++ - 为什么 std::mutex 需要很长时间才能共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53068526/

相关文章:

c++ - 在 Xcode 中编译 C++ 时出现很多错误

c++ - 采用可变参数模板包将 std::strings 转换为 const char * 的函数?

c++ - 涉及比较仿函数的循环依赖

linux - Linux pthread 中 SetThreadIdealProcessor 的替换

c - 使用信号量的有界缓冲区生产者-消费者代码

c++ - <regex> std::regex 相当于 Qt 的 QRegularExpression::isValid() 且不会触发异常

c++ - 根据非静态值对结构进行排序 (C++)

c++ - 为什么 std::numeric_limits::is_integer 对于 volatile 类型是假的?

c++ - WTL vista/7 原生外观中的 CreateSimpleReBar

c - 带有条件变量的简单生成器监控程序