这段代码演示了互斥锁在两个线程之间共享,但一个线程几乎一直拥有它。
#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/