我正在尝试使用Boostupgrade_lock
(using 这个例子 https://stackoverflow.com/questions/989795/example-for-boost-shared-mutex-multiple-reads-one-write,但我遇到了饥饿问题。
我实际上正在使用来自的代码这个帖子 https://stackoverflow.com/questions/12082405/boost-shared-lock-read-preferred/13445989#13445989,但我想要最新的讨论。我在之后运行了 400 个线程工人杀手。我遇到了完全相同的问题匿名者,上述帖子的作者。
我已经看到了来自霍华德·希南特,但我真的不想包含更多的外部代码(而且我现在无法编译他的代码),并且 6 个月后发布的评论指出“Boost 现在使用公平的实现“(2012 年 12 月 3 日)。
The Boost 1.55 文档 http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html指出:
Note the the lack of reader-writer priority policies in shared_mutex. This is
due to an algorithm credited to Alexander Terekhov which lets the OS decide
which thread is the next to get the lock without caring whether a unique lock or
shared lock is being sought. This results in a complete lack of reader or writer
starvation. It is simply fair.".
该算法归功于亚历山大·捷列霍夫是那个霍华德·希南特谈到,所以我希望 1.55 boost 实现的行为就像 Howard Hinnant 的答案一样,但事实并非如此。它的行为与问题中的完全一样。
为什么我的情况是这样工人杀手挨饿吗?
更新:观察到这段代码 https://gist.github.com/anonymous/bd3440d438da82061f22 on:
- Debian x64,Boost 1.55(Debian 版本和从源代码编译的版本),带有 clang++ 和 g++
- Ubuntu x64,Boost 1.54,带有 clang++ (3.4-1ubuntu1) 和 g++ (4.8.1-10ubuntu9)
这是一个微妙的问题。差异涉及共享和可升级所有权的概念及其在 Boost 中的实现。
让我们首先理清共享所有权和可升级所有权的概念。
为一个共享可锁定 http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.shared_lockable,线程必须事先决定是否要更改对象(需要独占所有权)或仅读取对象(共享所有权就足够了)。如果具有共享所有权的线程决定要更改该对象,则它首先必须释放该对象上的共享锁,然后构造一个新的排它锁。在这两个步骤之间,线程根本不持有对象的锁。尝试从已持有共享锁的线程构造排它锁将会死锁,因为排它锁构造函数将阻塞,直到所有共享锁被释放。
升级可锁定 http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.upgrade_lockable通过允许将共享锁升级为排它锁来克服此限制不释放它。也就是说,该线程始终保持互斥体上的活动锁,同时禁止其他线程获得排它锁。除此之外,UpgradeLockable 仍然允许来自 SharedLockable 的所有操作,前一个概念是后者的超集。这您链接到的问题 https://stackoverflow.com/questions/12082405/boost-shared-lock-read-preferred/13445989#13445989只关心 SharedLockable 概念。
正如 Boost 所指定的,这两个概念都不需要公平的实现。但是,那shared_mutex http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.shared_mutex,这是 Boost 对 SharedLockable 的最小实现,确实提供了您问题中引用的公平性保证。请注意,这是一个额外保证到这个概念的实际需要。
不幸的是,可升级所有权的最低实现,upgrade_mutex http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.upgrade_mutex,不提供这种额外的保证。它仍然实现共享所有权概念作为可升级所有权的要求,但由于一致性实现不需要公平,因此他们不提供它。
As 霍华德在评论中指出 https://stackoverflow.com/questions/21773618/starvation-with-upgrade-lock/21778949?noredirect=1#comment45138062_21778949,Terekhov 的算法也可以进行简单的调整以使用可升级的锁,只是 Boost 实现目前不支持这一点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)