C++14 shared_timed_mutex与C++11 mutex的比较

7

我有一个共享哈希表,由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();

如果你的示例更完整一些,那会非常有帮助。 - melak47
1个回答

13
由于您的问题有些含糊,而且除了您自己之外没有其他人可以重现这种行为,所以我只能猜测。 我最好的猜测是:`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%的机会让两个或更多线程同时运行,值得吗?这要看情况而定。

mutexshared_timed_mutex更简单。简单的代码可以带来更快的执行速度。

shared_timed_mutex在读者数量远远多于写者且读取任务相对于写入任务很长或很常见时表现出色。

例如,如果你有一个数据库,在被更新6次每年(每次需要1秒)之外保持不变,那么使用shared_timed_mutex以共享模式锁定该数据库进行读取是非常合理的。每两个月锁定一次独占模式也是容易接受的。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接