linux - 如何防止 pthreads 中读写锁中的写入器饥饿

标签 linux multithreading pthreads

我对 *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 中完成的,因为这就是我正在寻找的。

请注意,我只想要*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.cpthread_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/

相关文章:

c# - 无法写入输入以处理 C# Mono

c++ - 多线程上的信号量和临界区问题

java - 程序在遍历目录树时在 JTextArea 中显示文件名,但我不知道如何通过按键停止它

c - 信号量互斥锁防止死锁 - C 程序

c - 线程 : value stored in heap 问题

linux - 获取 linux shell 名称

linux - 操作系统什么时候检查信号?

c++ - 将值归一化到较小的范围

multithreading - 与仅使用多个流相比, fork 一个流有什么优势?

c - 可以在调用 pthread_cond_wait() 之前检查互斥锁是否已锁定吗?