經過this question with the same title及其答案後,我想嘗試一些應該只使用臨界區域才能真正起作用的東西,因此速度應該快於現有的解決方案(也使用其他內核對象像互斥或信號)只使用關鍵部分的讀/寫鎖會導致死鎖
這裏是我的讀/寫鎖定/解鎖功能:
#include <windows.h>
typedef struct _RW_LOCK
{
CRITICAL_SECTION readerCountLock;
CRITICAL_SECTION writerLock;
int readerCount;
} RW_LOCK, *PRW_LOCK;
void InitLock(PRW_LOCK rwlock)
{
InitializeCriticalSection(&rwlock->readerCountLock);
InitializeCriticalSection(&rwlock->writerLock);
}
void ReadLock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->readerCountLock); // In deadlock 1 thread waits here (see description below)
if (++rwlock->readerCount == 1)
{
EnterCriticalSection(&rwlock->writerLock); // In deadlock 1 thread waits here
}
LeaveCriticalSection(&rwlock->readerCountLock);
}
void ReadUnlock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->readerCountLock);
if (--rwlock->readerCount == 0)
{
LeaveCriticalSection(&rwlock->writerLock);
}
LeaveCriticalSection(&rwlock->readerCountLock);
}
int WriteLock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->writerLock); // In deadlock 3 threads wait here
}
void WriteUnlock(PRW_LOCK rwlock)
{
LeaveCriticalSection(&rwlock->writerLock);
}
這裏是一個線程函數。在從main
呼叫InitLock (&g_rwLock);
之後,我創建了五個線程來嘗試這些鎖。
void thread_function()
{
static int value = 0;
RW_LOCK g_rwLock;
while(1)
{
ReadLock(&g_rwlLock);
BOOL bIsValueOdd = value % 2;
ReadUnlock(&g_rwlLock);
WriteLock(&g_rwlLock);
value ++;
WriteUnlock(&g_rwlLock);
}
}
理想情況下,此代碼應該保持運行而不會有任何問題。但令我失望的是,它並沒有運行總是。有時它陷入僵局。我編譯並在Windows XP上運行它。要使用線程池創建線程,我正在使用第三方庫。因此,在這裏不能給出所有涉及大量初始化例程和其他內容的代碼。
但是爲了簡化故事,我想知道是否有人通過查看上面的代碼可以指出這種方法有什麼問題?
我已經在上面的代碼中註釋了每個線程(出於五個線程)在死鎖發生時一直等待。 (我發現通過附加調試器到死鎖進程)
任何輸入/建議將是非常好的,因爲我堅持了很長一段時間現在(在使我的代碼比以往更快運行的貪婪) 。
請注意,這是一個讀者優先鎖定 - 如果您的讀者數量從未達到0,寫入將永遠等待。如果這是不可取的,你可能想要考慮一個票務系統,如[Mellor-Crummey-Scott](http://www.cs.rochester.edu/u/scott/papers/1991_PPoPP_read_write.pdf)「公平「的鎖定。 – 2014-12-01 20:10:58
與往常一樣:_RW_LOCK是爲編譯器保留的名稱(前導下劃線後跟大寫字母) – 2014-12-01 20:11:12
請發佈演示此問題的*實際*代碼。這裏的代碼顯然已經在翻譯中失去了一些東西,正在浪費有用的人的時間。 – 2014-12-01 21:03:07