2010-02-03 101 views
23

我有一些關於* nix系統上的POSIX Pthreads讀寫鎖定的問題,比如Linux。如何在pthreads中阻止讀寫鎖定中的寫入器飢餓

我想知道什麼是讀寫鎖的默認偏差,即它喜歡讀取寫入還是反之呢?它提供了一些API來改變這種默認行爲。

posix pthread是否提供了一些API,以便我們可以更改pthread_rwlock_t以防止作家餓死?從我讀過的內容(如果我錯了,請糾正我),默認實現偏向讀者線程,因此編寫器線程可能面臨飢餓。

我已經閱讀了David Butenhof編寫的使用Posix線程編程的書中rw鎖的示例實現。

我想知道POSIX pthreads如何處理作家線程的匱乏?是否有一些使用我們可以設置讀寫鎖的屬性,以防止寫捱餓(我從來沒有聽說過)?或者用戶不得不處理這個問題?

如果你認爲答案是實現定義的,那麼請舉例說明它是如何在Linux中完成的,因爲那就是我正在尋找的。

請注意,我只想要一個* nix系統的解決方案。不要以爲我很粗魯,但發佈一些特定於Windows的代碼對我來說毫無用處。

謝謝大家的幫助和耐心:)

+0

使用互斥鎖而不是rwlock可以避免這個問題。如果爭用率較低,則在某些實現中(例如從互斥量和條件變量構建rwlock的實現)也會更快。 – jilles 2011-05-15 19:15:36

回答

35

這確實取決於執行方式 - 所以你既然問到Linux中,我的意見是指當前NPTL執行並行線程,這是用於現代glibc。

這裏有兩個相關的但是單獨的問題。首先,有這種情況:

  • 有讀鎖定當前舉行,和作家在等待。一個新線程嘗試讀取鎖定。

此處的默認操作是讓讀者繼續 - 有效地在作者身上「跳過隊列」。然而,你可以重寫這個。如果您使用pthread_rwlockattr_setkind_np()函數將上的PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP標誌設置爲pthread_rwlock_init(),那麼在上述情況下,您的rwlock將阻止閱讀器。

第二種情況是:

  • 最後持有者釋放鎖,有讀者和作家等。

在這種情況下,NPTL總是會喚醒作者而不是讀者。

總之,上述意味着,如果你使用的PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP標誌,你的作家不應該被餓死(當然,現在的作家的連續流可以餓死讀者。這就是生活)。您可以通過檢查pthread_rwlock_rdlock.cpthread_rwlock_unlock.c中的來源(全部非常易讀)來確認所有這些情況。

注意,也有PTHREAD_RWLOCK_PREFER_WRITER_NP,但它似乎沒有有正確的效果 - 很可能是一個錯誤(或可能不 - 見comment by jilles below)。

+0

非常感謝。這就是我一直在尋找的東西。還有一件事,函數pthread_rwlockattr_setkind_np()是一個POSIX api還是隻有linux特定的?我在linux系統的/usr/include/pthread.h頭文件中看不到它(可能是它的舊版本)。 「np」代表什麼?非常感謝:) – ghayalcoder 2010-02-03 08:10:48

+1

它在這裏被列爲UNIX98擴展名:http://nptl.bullopensource.org/Tests/Optimization-level-in-nptl.html但我認爲這是一個錯誤,它實際上是一個GNU擴展(as是'_np'結尾的所有其他函數)。當然在實踐中,這在其他地方是不可用的。我認爲'_np'是'NPTL'的縮寫,意思是「Native POSIX線程庫」。我不確定到底是哪個版本的glibc引入了它,但我的盒子上的glibc 2.7具有它。也許在glibc郵件列表上問一下? – caf 2010-02-03 22:03:28

+0

非常感謝caf :) – ghayalcoder 2010-02-19 09:11:57