我的代碼有一個rw_sempaphore
,通過對我的功能unlock()
的單個調用即可解鎖。但是,當我的代碼被調用時,它不知道它當前是否具有讀取或寫入鎖定。所以它不知道它是否應該叫up_write()
或up_read()
。使用讀取或寫入鎖定rw_semaphore
我可以一個接一個地調用兩個,沒有任何負面影響嗎?有沒有辦法判斷當前線程是否有讀或寫鎖定?
我試着打電話downgrade_write()
,然後up_read()
,但這似乎並不奏效。降級讀鎖是不好的?
我的代碼有一個rw_sempaphore
,通過對我的功能unlock()
的單個調用即可解鎖。但是,當我的代碼被調用時,它不知道它當前是否具有讀取或寫入鎖定。所以它不知道它是否應該叫up_write()
或up_read()
。使用讀取或寫入鎖定rw_semaphore
我可以一個接一個地調用兩個,沒有任何負面影響嗎?有沒有辦法判斷當前線程是否有讀或寫鎖定?
我試着打電話downgrade_write()
,然後up_read()
,但這似乎並不奏效。降級讀鎖是不好的?
我最終存儲了使用down_write()
的進程的PID。 unlock()
函數檢查是否匹配PID,如果匹配,則執行up_write()
。否則,它確實是up_read()
。
不是最漂亮的,但它的工作原理。
我可以一個接一個地調用兩個,沒有任何負面影響嗎?
當然不是!想象一下:
thread A thread B:
down_write
down_read (blocked)
...
unlock
|\ up_write
| (released, acquired read lock)
| ...
\ up_read (lock messed up)
我從來沒有使用rw_semaphore
,但如果它是一個單一的作家,多讀鎖,那麼這就是你的解決方案。
編輯:請注意,這要求鎖是遞歸的。在rw_semaphore
的情況下,事實證明這確實是而不是遞歸。
的問題很容易解決,如果我們可以檢測鎖是否被鎖定在讀取或寫入模式(假設你已經知道它是鎖定在這些模式中的一種,即它不是解鎖)。
因爲鎖是多閱讀器,那麼我們可以用一個讀嘗試鎖知道的情況:
if (down_read_trylock(sem))
/* semaphore was locked in read mode */
else
/* semaphore was locked in write mode */
在if
情況下,信號已鎖定在讀模式,和我們再次鎖定它,所以它需要兩個up_read
s。在其他情況下,信號量被鎖定在寫入模式下,所以我們需要一個up_write
。這假定down_read_trylock
不會因最大數量的讀取鎖定或任何其他原因而失敗,除非鎖定處於寫入模式。
所以在最後:
void unlock(struct rw_semaphore *sem)
{
if (down_read_trylock(sem))
{
up_read(sem);
up_read(sem);
}
else
up_write(sem);
}
注意:使用前測試!
這聽起來不錯,但我不認爲'rw_semaphore's可以遞歸。除非我誤解了http://lxr.free-electrons.com/source/include/linux/rwsem.h#L114。我可以使用嵌套功能,或者不能保證它存在 – zsalzbank 2013-03-07 15:45:08
你是對的。這似乎與'* _nested'函數可能是可能的,但我真的不知道。黑客應該檢查信號量的「count」字段。快速查看顯示'count == -1'表示寫鎖定,'count> 0'表示讀鎖定。 – Shahbaz 2013-03-07 16:08:18
我想這會起作用。或者我想我可以使用除'rw_semaphore'之外遞歸的鎖定機制,儘管它不會那麼漂亮。 – zsalzbank 2013-03-07 17:34:52