我有一个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();发布于 2015-10-02 11:47:11
由于你的问题有点含糊,除了你自己之外,任何人都不能复制这种行为,我只能猜测。
我最好的猜测是:
shared_timed_mutex并不总是比mutex更好。如果是这样的话,就不需要mutex了。我们只需要去掉mutex,将shared_timed_mutex重命名为mutex,然后幸福地生活在一起。不幸的是,现实生活要比这复杂得多。
有时mutex是最好的工具。有时shared_timed_mutex是最好的工具。
例如:如果我们有8个线程竞争互斥锁,每个线程有50%的概率需要读或写,而读写任务需要保持互斥锁大致相同的时间,那么使用shared_timed_mutex类型几乎没有什么好处。
要理解这一点,请考虑所有8个线程同时请求shared_timed_mutex的场景。在这种情况下,写入者首先获得它(50%的概率),然后所有其他7个线程阻塞(就像我们使用mutex一样)。
在另外50%的时间里,读者会先得到它。请求锁的第二个线程有50/50的机会成为读取器。如果它是一个写入器,一个公平的实现将阻止其余的读取器获取锁。这种情况发生在0.5 * 0.5 == 25%的情况下。所以现在我们有75%的时间,一次只能运行一个线程:{W,block...}和{R,W,block...}。
25%的时间我们得到一个{R,R,?...},其中至少有两个线程可以同时运行。
好吧,至少25%让两个甚至更多的线程同时运行不是值得的吗?
那得看情况。
mutex比shared_timed_mutex更简单。更简单的代码会导致更快的代码。
当读取器的数量远远超过写入器的数量,并且与写入器任务相比,读取器任务很长和/或很常见时,shared_timed_mutex就会大放异彩。
例如,如果您有一个数据库,除了一年更新6次(更新耗时1秒)之外,它一直保持不变,那么在共享模式下锁定shared_timed_mutex读取该数据库非常有意义。人们可以很容易地在独特的模式下每两个月锁定它一次。
但是,如果您每秒都要更新该数据库,情况就完全不同了,shared_timed_mutex可能根本不会为您提供任何性能优势。在这种情况下,只要求每个人(读取者和写入者)请求独占访问可能会更便宜(因为逻辑更简单)。
https://stackoverflow.com/questions/32894027
复制相似问题