C ++ 14 shared_timed_mutex VS C ++ 11互斥锁

时间:2015-10-01 18:03:02

标签: c++ multithreading mutex c++14

我在8个线程(我是一个8核PC)之间有一个共享哈希表,每个线程都在哈希表中读写。

在示例1中,我使用了经典的互斥锁,所有8个核心都是100% 在示例2中,我使用了shared_timed_mutex,因为读访问可以在竞争中,但所有8核都在40%

问题出在哪里?

example 1:
mutex mutex_hash;

-- thread --
mutex_hash.lock();
//read
mutex_hash.unlock();
..
mutex_hash.lock();
//write
mutex_hash.unlock();

============================

example 2:
shared_timed_mutex mutex_hash;

-- thread --
mutex_hash.lock_shared();
//read
mutex_hash.unlock_shared();
..
mutex_hash.lock();
//write
mutex_hash.unlock();

1 个答案:

答案 0 :(得分:6)

由于你的问题有些含糊不清,除了你自己以外的任何人都无法重现这种行为,我只能猜测。

我最好的猜测是:

shared_timed_mutex并不总是比mutex好。如果是,则不需要mutex。我们只需要摆脱mutex,将shared_timed_mutex重命名为mutex,然后过上幸福的生活。不幸的是,现实生活比这复杂得多。

有时mutex是优秀的工具。有时shared_timed_mutex是优秀的工具。

例如:如果我们有8个线程争用互斥锁,并且每个线程有50%的概率需要读取或写入,并且读取和写入任务需要保持互斥量大约相同的时间量,那么那里使用shared_timed_mutex类型收效甚微。

要理解这一点,请考虑同时请求shared_timed_mutex的所有8个线程的场景。如果作者首先得到它(概率为50%),则所有其他7个线程都会阻塞(就像我们使用mutex一样)。

在另外50%的时间里,读者首先得到它。请求锁定的第二个线程有50/50的机会成为读者。如果是作家,公平的实施将阻止其余的读者获得锁定。这发生在0.5 * 0.5 == 25%的时间。所以现在我们高达75%的时间,一次只能运行一个线程:{W,阻止...}和{R,W,阻止......}。

25%的时间我们得到{R,R,?...},其中至少有两个线程可以同时运行。

嗯,至少25%没有两个,也许更多线程一次运行值得吗?

取决于。

mutexshared_timed_mutex简单。更简单的代码可以实现更快的代码。

当读者远远超过作者,并且读者任务与作家任务相比较长和/或普通时,

shared_timed_mutex会发光。

例如,如果您的数据库保持不可变,除了每年更新6次(并且需要1秒更新),读取该数据库并锁定共享shared_timed_mutex是很有意义的模式。人们可以轻松地以独特模式每两个月锁定一次。

但是,如果您每秒都尝试更新该数据库,这是完全不同的情况,shared_timed_mutex可能根本不会为您提供任何性能优势。在这种情况下,要求每个人(读者和作者)要求独占访问(因为逻辑更简单)可能更便宜。