我对* nix系统上的POSIX Pthreads中的读写锁有一些疑问,例如Linux。
我想知道读写锁的默认偏差是什么,它是否更喜欢读取写入,反之亦然?它是否提供了一些api来更改此默认行为。
posix pthread是否提供了一些api,以便我们可以更改pthread_rwlock_t以防止写入者饥饿?从我所读到的(如果我错了请纠正我),默认实现偏向于读者线程,因此作者线程可能面临饥饿。
我已经阅读了David Butenhof的“使用Posix线程编程”一书中的rw锁示例实现。
我想知道posix pthreads如何处理编写器线程的饥饿?是否有一些api使用,我们可以设置读写锁的属性,以防止写饥饿(我从来没有听说过)?或者用户是否必须处理此问题?
如果您认为答案是实现定义的,那么请举例说明它是如何在Linux中完成的,因为这就是我想要的。
请注意,我只想要一个* nix系统的解决方案。不要以为我很粗鲁,但发布一些特定于Windows的代码对我来说毫无用处。
感谢大家的帮助和耐心:)
答案 0 :(得分:42)
这确实取决于实现 - 所以既然你已经专门询问了Linux,我的评论是指现代的glibc中使用的pthreads的NPTL实现。
这里有两个相关但又分开的问题。首先,有这种情况:
这里的默认操作是允许读者继续 - 有效地“跳过队列”在作者身上。但是,您可以覆盖它。如果您使用pthread_rwlockattr_setkind_np()
函数在传递给PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
的{{1}}上设置attr
标记,那么您的rwlock将在上述情况下阻止读者。
第二种情况是:
在这种情况下,NPTL总会唤醒作家而不是读者。
总而言之,上述意味着如果你使用pthread_rwlock_init()
旗帜,你的作家就不应该被挨饿(当然,现在连续不断的作家可以让读者们挨饿。 C'est la VIE )。您可以通过检查pthread_rwlock_rdlock.c和pthread_rwlock_unlock.c中的来源(它们都是非常易读的 1 )来确认所有这些。
请注意,还有一个PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
,但似乎不才能产生正确的效果 - 很可能是一个错误(或可能不是 - 请参阅comment by jilles below )。
<小时/> 1。 ...或者至少在2010年我写这个答案的时候回来了。最新版本的NPTL要复杂得多,我还没有重新进行分析。