此代码演示了互斥体在两个线程之间共享,但一个线程几乎始终拥有它。
#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 编译。
输出是两者的混合#
and .
字符,表明互斥锁正在被共享,但模式令人惊讶。通常是这样的:
.......#####..........................##################......................##
即thread_lock
锁定互斥锁very很久。几秒甚至几十秒后,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);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)