![](/img/trans.png)
[英]Can thread trying to std::lock[_unique] an std::shared_mutex be starved by threads calling std::lock_shared?
[英]std::shared_mutex not scaling with threads doing lock_shared()
我编写了一个简单的程序来测试std::shared_mutex
在多个循环lock_shared()
的线程中的性能。 但从结果来看,它似乎并没有随着添加更多线程而扩展,这对我来说真的没有意义。
您可能会争辩说这是因为stopFlag
限制了性能,所以第二个 for 循环测试增加本地计数器,这在开始时几乎是完美的缩放
注释中的结果是使用带有Release
标志的MSVC
编译的。
int main()
{
const auto threadLimit = std::thread::hardware_concurrency() - 1; //for running main()
struct SharedMutexWrapper
{
std::shared_mutex mut;
void read()
{
mut.lock_shared();
mut.unlock_shared();
}
};
/*Testing shared_mutex */
for (auto i = 1; i <= threadLimit; ++i)
{
std::cerr << "Testing " << i << " threads: ";
SharedMutexWrapper test;
std::atomic<unsigned long long> count = 0;
std::atomic_bool stopFlag = false;
std::vector<std::thread> threads;
threads.reserve(i);
for (auto j = 0; j < i; ++j)
threads.emplace_back([&] {unsigned long long local = 0; while (!stopFlag) { test.read(); ++local; } count += local; });
std::this_thread::sleep_for(std::chrono::seconds{ 1 });
stopFlag = true;
for (auto& thread : threads)
thread.join();
std::cerr << count << '\n';
}
/*
Testing 1 threads: 60394076
Testing 2 threads: 39703889
Testing 3 threads: 23461029
Testing 4 threads: 16961003
Testing 5 threads: 12750838
Testing 6 threads: 12227898
Testing 7 threads: 12245818
*/
for (auto i = 1; i <= threadLimit; ++i)
{
std::cerr << "Testing " << i << " threads: ";
std::atomic<unsigned long long> count = 0;
std::atomic_bool stopFlag = false;
std::vector<std::thread> threads;
threads.reserve(i);
for (auto j = 0; j < i; ++j)
threads.emplace_back([&] {unsigned long long local = 0; while (!stopFlag) ++local; count += local; });
std::this_thread::sleep_for(std::chrono::seconds{ 1 });
stopFlag = true;
for (auto& thread : threads)
thread.join();
std::cerr << count << '\n';
}
/*
Testing 1 threads: 3178867276
Testing 2 threads: 6305783667
Testing 3 threads: 9388659151
Testing 4 threads: 12472666861
Testing 5 threads: 15230810694
Testing 6 threads: 18130479890
Testing 7 threads: 20151074046
*/
}
在共享互斥锁上放置读锁会修改该互斥锁的 state。 您的所有线程都只尝试更改共享互斥锁 object 的 state 。 所以当然,这段代码的扩展性很差。
共享互斥锁的意义在于允许访问未按比例修改的共享数据。 您无权访问未修改的共享数据。 因此,您没有在这里测量共享互斥锁的任何有益属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.