std :: shared_mutex比作家更喜欢作家吗?

时间:2019-08-29 09:18:20

标签: c++ multithreading

自C ++ 17(C ++ 14)起,我们有了std :: shared_(timed_)mutex类。 Qt长期以来都有一个类似的类QReadWriteLock。 QReadWriteLock的documentation说:

  

为了确保作家不会被读者永远阻止,读者   如果被阻止,尝试获取锁将不会成功   写者等待访问,即使当前仅访问锁   由其他读者。另外,如果写者访问了该锁,并且   另一个作家进来,那个作家将优先于任何   可能也正在等待的读者。

因为这当然是一个合理的属性,所以我想知道是否 std::shared_mutexstd::shared_timed_mutex的行为类似吗?

2 个答案:

答案 0 :(得分:2)

官方C ++标准未指定std::shared_mutex策略。可以在原始N2406建议中找到说明 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#shared_mutex_imp)在 shared_mutex参考实现部分:

  

第二个动机是解释shared_mutex中缺少读写器优先级策略。这是由于归功于Alexander Terekhov的算法,该算法使OS可以决定哪个线程是获得该锁的下一个线程,而无需关心是否正在寻找唯一锁或共享锁。这导致完全缺乏读者或作家的饥饿。这很公平。

与QReadWriteLock实现(即 write-preferring )相比:

  

为确保不会永远被写入者阻止写入者,即使有阻塞的写入者正在等待访问,即使当前仅由其他读取者访问该锁定,尝试获取锁定的读取者也不会成功。

对于提案的shared_mutex也是如此,以确保如果新读者继续涌现,作家不会永远等待。

  

此外,如果一个写程序访问了该锁并且另一个写程序进入,则该写程序的优先级高于可能也在等待的所有读程序。

对于提案的shared_mutex并非如此,在这种情况下,读者和作者具有同等的优先级。

但是很遗憾,最终的C ++ Standard文档不包含此参考实现。请注意,尽管GCC包含基于N2406参考实现的std::shared_mutex实现,但是在Linux上默认未使用它,但是它使用POSIX线程lib中的pthread_rwlock_t(由_GLIBCXX_USE_PTHREAD_RWLOCK_T选项控制在c++config.h中)。根据系统设置和所应用的pthread_rwlock_t属性,可以优先选择pthread或首选写入。有关详情,请参见相关问题:How to prevent writer starvation in a read write lock in pthreads

答案 1 :(得分:2)

标准未指定。

POSIX没有指定pthread rwlocks必须如何确定下一个成功的锁定请求,因此,如果有这样的要求,就不可能在标准pthread上实现C ++ std::shared_mutex

  

因为这当然是合理的属性

这当然是 a 合理的属性,但它不是 only 合理的属性。

例如,GLIBC具有pthreads扩展名,使您可以从三个rwlock策略中进行选择:递归首选阅读器,递归首选编写器和非递归首选编写器。可能递归首选作者并不是所有程序的正确选择。


  

为确保作家不会被读者永远阻止...

顺便说一句,这并不能确保作家不会被其他作家永远阻止。

直观上完美的解决方案是共享阅读器首选排他的FIFO排序写入器,但这对于许多目的来说都是不必要的重量级。

对于Qt的用例来说,Qt版本可能是完美的选择,但在轻量级/高效-重度/中等频谱上只有一点。