2017-06-20 34 views
1

我正在嘗試實現以下方案。如果系統中只有讀者,請不要使用互斥鎖。我寫了下面的實現。讀寫器併發性

LockReader() 
{ 
    flag = 0; 
    atomic increment cntReader; 
    if(atomic check cntWriter > 0) 
    { 
    while(noLock != 0); 
    flag = 1; 
    mutexLock(var); 
    } 
    else 
    { 
    atomic increment noLock; 
    } 

    //CS 

    if(flag == 1) 
    mutexUnlock(var); 
    else 
    atomic decrement noLock; 

    atomic decrement cntReader; 
} 

LockWriter() 
{ 
    atomic increment cntWriter; 
    if(atomic check cntReader > 0) 
    { 
    while(noLock != 0); 
    } 

    mutexLock(var); 

    mutexUnlock(var); 
    atomic decrement cntWriter; 

} 

但這個代碼有問題,如果有一個閱讀器,它評估LockShared的3線(if(cntWriter > 1))後得到上下文切換和作家來了,那麼就可以得到mutexLock,因爲NOLOCK不遞增。在mutexLock之後,如果作者是上下文切換的,讀者也將被允許。我們已經讓讀者和作家一起。

如何避免這種情況?

編輯1: 我已經改變LockReader()是這樣的:

LockReader() 
{ 
    flag = 0; 
    atomic increment cntReader; 
    atomic increment noLock; 
    if(atomic check cntWriter > 0) 
    { 
    atomic decrement noLock; 
    while(noLock != 0); 
    flag = 1; 
    mutexLock(var); 
    } 

    //CS 

    if(flag == 1) 
    mutexUnlock(var); 
    else 
    atomic decrement noLock; 

    atomic decrement cntReader; 
} 

我想,這應該可以解決我提到的問題。但是是否還有其他讀寫器併發性問題?

編輯2:增加了解鎖碼。

+0

你爲什麼要這麼做?無人看管的鎖應該不昂貴。似乎錯誤的優化。 –

+0

爲了保持完整性,您能否提供相應的解鎖功能? –

+0

@JohnZwinck我正在努力提高性能。甚至對讀者來說,獨佔互斥鎖也會嚴重降低性能。 – user2761431

回答

0

如果是關於性能的全部內容,則根本不應該使用互斥鎖。而是隻使用一個計數器並忙於等待,即:

volatile int rw_lock; 

LockReader() { 
    int l, success = 0; 

    while (success == 0) { 
     l = rw_lock; 
     if (l < 0) { 
      // wait for a writer 
      continue; 
     } 
     // atomically increment rw_lock 
     success == cmpset(rw_lock, l, l + 1); 
    } 
} 

LockWriter() { 
    int l, success = 0; 

    while (success == 0) { 
     l = rw_lock; 
     if (l != 0) { 
      // wait for readers 
      continue; 
     } 
     // atomically set rw_lock to -1 
     success = cmpset(rw_lock, 0, -1); 
    } 
} 

UnlockReader() { 
    atomic_dec(rw_lock); 
} 

UnlockWriter() { 
    atomic_inc(rw_lock); 
} 

這些類型的鎖稱爲讀寫器鎖。您可以在維基百科的更多信息:

https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock

編輯: 寫寧願版本:

volatile int rw_lock; 
volatile int w_req; 

LockReader() { 
    int l, success = 0; 

    while (success == 0) { 
     while (w_req) { 
      // wait due to write preference 
     } 
     l = rw_lock; 
     if (l < 0) { 
      // wait for a writer 
      continue; 
     } 
     // atomically increment rw_lock 
     success == cmpset(rw_lock, l, l + 1); 
    } 
} 

LockWriter() { 
    int l, success = 0; 

    w_req = 1; // request a write, i.e. block new reads 
    while (success == 0) { 
     l = rw_lock; 
     if (l != 0) { 
      // wait for readers 
      continue; 
     } 
     // atomically set rw_lock to -1 
     success = cmpset(rw_lock, 0, -1); 
    } 
    w_req = 0; // allow new reads 
} 

UnlockReader() { 
    atomic_dec(rw_lock); 
} 

UnlockWriter() { 
    atomic_inc(rw_lock); 
} 
+0

由於無法使用'__sync_val_compare_and_swap',因此產品支持的gcc是4.3.4 – user2761431

+0

此外,代碼可能導致作家餓死?我的觀察是否正確? – user2761431

+0

@ user2761431 1.您需要__sync_bool_compare_and_swap,並且它應該在gcc 4.3.4中可用2.請參閱維基百科鏈接,這裏有Write-preferring RW鎖。 –