【问题标题】:C++14 shared_timed_mutex VS C++11 mutexC++14 shared_timed_mutex VS C++11 互斥量
【发布时间】:2015-12-29 21:19:06
【问题描述】:

我有一个 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();

【问题讨论】:

  • 如果你的例子更完整,那真的很有帮助。

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


【解决方案1】:

由于您的问题有些模糊,并且除了您自己之外的任何人都无法重现该行为,我只能猜测。

我的最佳猜测是:

shared_timed_mutex 并不总是比mutex 好。如果是,就不需要mutex。我们将摆脱mutex,将shared_timed_mutex 重命名为mutex,从此过上幸福的生活。不幸的是,现实生活比这更复杂。

有时mutex 是最好的工具。有时shared_timed_mutex 是最好的工具。

例如:如果我们有 8 个线程竞争 mutex,并且每个线程有 50% 的概率需要读取或写入,并且读取和写入任务需要持有 mutex 的时间大致相同,那么有使用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 可能根本不会为您提供任何性能优势。在这种情况下,只要求每个人(读者和作者)请求独占访问可能会更便宜(因为逻辑更简单)。

【讨论】:

    猜你喜欢
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多