我对 *nix 系统(例如 Linux)上的 POSIX Pthreads 中的读写锁有一些疑问。
我想知道读写锁的默认偏向是什么,即它更喜欢读还是写,反之亦然?它是否提供一些 API 来更改此默认行为。
posix pthread 是否提供一些 api 以便我们可以更改 pthread_rwlock_t 以防止 writer starvation?根据我所读的内容(如果我错了请纠正我),默认实现偏向于读者线程,因此作者线程可能面临饥饿。
我已从 David Butenhof 的《Programming with Posix threads》一书中阅读了 rw lock 的示例实现。
我想知道 posix pthreads 如何处理 writer threads 饥饿?是否有一些 api 可以用来设置读写锁的属性以防止写饥饿(我从未听说过)?还是用户必须处理这个问题?
如果您认为答案是实现定义的,那么请举例说明它是如何在 Linux 中完成的,因为这就是我正在寻找的。strong>
请注意,我只想要*nix 系统的解决方案。不要以为我很粗鲁,但是发布一些特定于 Windows 的代码对我来说毫无用处。
谢谢大家的帮助和耐心:)
最佳答案
这确实取决于实现 - 所以既然你已经专门询问了 Linux,我的评论是指 pthreads 的当前 NPTL 实现,它在现代 glibc 中使用。
这里有两个相关但独立的问题。首先是这种情况:
- 当前持有读取锁,等待写入。一个新线程尝试获取读锁。
此处的默认操作是允许读者继续 - 有效地“插队”而不是作者。但是,您可以覆盖它。如果您使用 pthread_rwlockattr_setkind_np()
函数在您传递给 pthread_rwlock_init()
的 attr
上设置 PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
标志>,那么你的rwlock会在上面的情况下阻塞reader。
第二种情况是:
- 最后一个持有者释放锁,同时有读者和写者等待。
在这种情况下,NPTL 总是会优先唤醒写入者而不是读取者。
综上所述,以上意味着如果你使用 PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
标志,你的作者不应该饿死(当然,现在连续不断的作者流可以让读者饿死。C 'est la vie)。您可以通过检查 pthread_rwlock_rdlock.c 和 pthread_rwlock_unlock.c 中的源代码(它们都非常可读1)来确认所有这些。
请注意,还有一个 PTHREAD_RWLOCK_PREFER_WRITER_NP
,但它似乎没有具有正确的效果 - 很可能是一个错误(或者可能不是 - 参见 comment by jilles below ).
<补充>1。 ...或者至少在 2010 年我写这个答案时是这样。最新版本的 NPTL 复杂得多,我没有重新进行分析。
关于linux - 如何防止 pthreads 中读写锁中的写入器饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2190090/