簡體   English   中英

pthread rwlock:wrlock內部的rdlock

[英]pthread rwlock: rdlock inside wrlock

情況:

  • 程序正在使用pthread_rwlock_t ,說foolock
  • 線程(例如T1)獲取foolock上的寫鎖(使用pthread_rwlock_wrlock()獲得)
  • T1嘗試獲取foolock上的讀鎖( pthread_rwlock_rdlock()
  • 沒有其他線程在foolock上擁有讀鎖定或寫鎖定
  • 有匹配的解鎖。

預計會發生什么?

程序(特別是T1)收到錯誤:

pthread_rwlock_rdlock() returns EDEADLK ("Resource deadlock avoided").

選擇這種行為的動機是什么? 如果授予讀鎖定,將會有什么問題?

解決這種情況的好方法是什么? 也許,T1需要保持某種狀態,即它已經對foolock持有寫鎖定。 還有其他建議嗎?

我的測試平台是Linux 2.6.32-431.11.2.el6.x86_64,NPTL 2.12

編輯1:很少有澄清:

  • 我不嘗試將讀取鎖升級為寫入鎖
  • 我不是想將寫鎖降級為讀鎖
  • 我正在研究是否已獲得寫鎖定時是否可以准予讀鎖定請求。

簡化上下文:

  • 我正在嘗試提供兩個公共API:(1) find()和(2) update()
  • find()使用讀取鎖
  • update()使用寫鎖
  • update()實現要調用find()<<- 問題

我當前的方法是:

  • 讓每個公共API都有相應的無鎖私有版本
  • 公用API執行3個步驟:

    • (a)取得適當的鎖,
    • (b)調用私人版本,
    • (c)釋放鎖

POSIX很清楚在pthread_rwlock_rdlock()中:

如果在調用時它擁有寫鎖,則調用線程可能會死鎖。

並在pthread_rwlock_wrlock()中:

如果在調用時它擁有讀寫鎖(無論是讀鎖還是寫鎖),則調用線程可能會死鎖。

我懷疑這是為了使事情簡單。

將讀鎖提升為寫鎖的功能看起來很有用,但(不幸的是)沒有。 考慮一個“索引”數據結構,其中“查找”會自動添加未找到的值:當查找未找到給定值時,最好提升讀取鎖,然后繼續將值添加到索引中在此基礎上沒有任何變化。 不幸的是,這是行不通的:考慮兩個同時運行的查找都需要寫鎖:-(因此,迫使程序員放棄讀鎖並獲得寫鎖,至少可以很清楚地知道是什么正在發生。

請注意,如果“索引查找”在確定需要寫鎖定時可以保持“ n”個讀鎖定,則存在問題,特別是如果它無法知道“ n”是什么時:- (至少能夠通過詢問rwlock來發現'n'會很不錯!

順便說一句,我發現FreeBSD具有:

rw_try_upgrade(結構rwlock * rw)

嘗試將單個共享鎖升級為獨占鎖。 當前線程必須持有rw的共享鎖。 僅當當前線程持有rw上的唯一共享鎖並且僅持有單個共享鎖時,此操作才會成功。 如果嘗試成功,則rw_try_upgrade()將返回非零值,並且當前線程將持有排他鎖。 如果嘗試失敗,則rw_try_upgrade()將返回零,並且當前線程仍將持有共享鎖。

...但是我注意到所有關於何時實際執行任何操作的警告!


關於將寫鎖降級為讀鎖的問題...

...如果沒有待處理的寫鎖,則語義非常清楚。 但是,如果有一個或多個待處理的作者,事情就不是那么簡單。

當前,程序員被迫放棄寫鎖定並獲得讀鎖定,這很清楚發生了什么。

如果將“降級”操作定義為原子的“寫解鎖/讀取鎖定”,那么這可能會使讀者領先於任何未決的作者,或者僅在沒有待決的作家的情況下才讓讀者進入。讓我感到更好的選擇。 “降級”的優勢在於降級后,人們知道狀態沒有再次改變-我想這很有用。

如果將持有寫鎖的pthread_rwlock_rdlock()定義為“降級”,則需要弄清楚將導致多少級鎖。如果結果是兩個鎖,則將釋放第二個鎖(讀為-鎖定)重新獲取第一個(寫鎖定)還是保留其讀鎖定狀態? [如果有可能將讀取鎖“升級”到寫入鎖,那么如何將讀取鎖/寫入鎖/升級/降級/解鎖的任意序列定義為有效?]

您已經具有讀取鎖,因為寫入鎖允許讀取寫入。

因此,您所要求的實際上是一個遞歸rwlock,而未提供遞歸rwlock的原因可能是遞歸鎖既更復雜,而且通常一開始就表明操作不當。

如果您真的無法重新編寫代碼,使其知道持有什么鎖,那么我同意您的想法,即在某些特定於線程的結構中跟蹤該狀態。 等效於C ++中流行的鎖衛類型的東西將是一個很好的選擇。

gmch指出,單獨的讀寫升級情況還有很多其他問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM