2013-03-07 75 views
2

我的代碼有一個rw_sempaphore,通過對我的功能unlock()的單個調用即可解鎖。但是,當我的代碼被調用時,它不知道它當前是否具有讀取或寫入鎖定。所以它不知道它是否應該叫up_write()up_read()使用讀取或寫入鎖定rw_semaphore

我可以一個接一個地調用兩個,沒有任何負面影響嗎?有沒有辦法判斷當前線程是否有讀或寫鎖定?

我試着打電話downgrade_write(),然後up_read(),但這似乎並不奏效。降級讀鎖是不好的?

回答

1

我最終存儲了使用down_write()的進程的PID。 unlock()函數檢查是否匹配PID,如果匹配,則執行up_write()。否則,它確實是up_read()

不是最漂亮的,但它的工作原理。

1

我可以一個接一個地調用兩個,沒有任何負面影響嗎?

當然不是!想象一下:

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); 
} 

注意:使用前測試!

+0

這聽起來不錯,但我不認爲'rw_semaphore's可以遞歸。除非我誤解了http://lxr.free-electrons.com/source/include/linux/rwsem.h#L114。我可以使用嵌套功能,或者不能保證它存在 – zsalzbank 2013-03-07 15:45:08

+0

你是對的。這似乎與'* _nested'函數可能是可能的,但我真的不知道。黑客應該檢查信號量的「count」字段。快速查看顯示'count == -1'表示寫鎖定,'count> 0'表示讀鎖定。 – Shahbaz 2013-03-07 16:08:18

+0

我想這會起作用。或者我想我可以使用除'rw_semaphore'之外遞歸的鎖定機制,儘管它不會那麼漂亮。 – zsalzbank 2013-03-07 17:34:52