如何在pthreads中的读写锁中防止编写器饥饿

时间:2010-02-03 06:21:47

标签: linux multithreading pthreads

我对* nix系统上的POSIX Pthreads中的读写锁有一些疑问,例如Linux。

我想知道读写锁的默认偏差是什么,它是否更喜欢读取写入,反之亦然?它是否提供了一些api来更改此默认行为。

posix pthread是否提供了一些api,以便我们可以更改pthread_rwlock_t以防止写入者饥饿?从我所读到的(如果我错了请纠正我),默认实现偏向于读者线程,因此作者线程可能面临饥饿。

我已经阅读了David Butenhof的“使用Posix线程编程”一书中的rw锁示例实现。

我想知道posix pthreads如何处理编写器线程的饥饿?是否有一些api使用,我们可以设置读写锁的属性,以防止写饥饿(我从来没有听说过)?或者用户是否必须处理此问题?

如果您认为答案是实现定义的,那么请举例说明它是如何在Linux中完成的,因为这就是我想要的。

请注意,我只想要一个* nix系统的解决方案。不要以为我很粗鲁,但发布一些特定于Windows的代码对我来说毫无用处。

感谢大家的帮助和耐心:)

1 个答案:

答案 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.cpthread_rwlock_unlock.c中的来源(它们都是非常易读的 1 )来确认所有这些。

请注意,还有一个PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,但似乎才能产生正确的效果 - 很可能是一个错误(或可能不是 - 请参阅comment by jilles below )。

<小时/> 1。 ...或者至少在2010年我写这个答案的时候回来了。最新版本的NPTL要复杂得多,我还没有重新进行分析。