summary:
分析讀寫鎖的特性,**以windows為例。但是其實讀寫鎖最先是linux裡面有的,所以說,下面的分析,適用於linux和windows平台。
wiki:
(1)讀寫鎖
讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進行讀訪問,寫者則需要對共享資源進行寫操作。這種鎖相對於自旋鎖而言,能提高併發性,因為在多處理器系統中,它允許同時有多個讀者來訪問共享資源,最大可能的讀者數為實際的邏輯cpu數。寫者是排他性的,乙個讀寫鎖同時只能有乙個寫者或多個讀者(與cpu數相關),但不能同時既有讀者又有寫者。
在讀寫鎖保持期間也是搶占失效的。
基本功能特點:
如果讀寫鎖當前沒有讀者,也沒有寫者,那麼寫者可以立刻獲得讀寫鎖,否則它必須自旋在那裡,直到沒有任何寫者或讀者。如果讀寫鎖沒有寫者,那麼讀者可以立即獲得該讀寫鎖,否則讀者必須自旋在那裡,直到寫者釋放該讀寫鎖。
具體分情況來說,乙個讀寫鎖的狀態有:
a, 沒有讀者,沒有寫者:寫者可以獲得鎖,讀者可以獲得鎖;
b, 有讀者,沒有寫著:寫著不能獲得鎖,讀者可以獲得鎖;
c, 沒有讀者,有寫著:寫著不能獲得鎖,讀者可以獲得鎖。
d, 有讀者,有寫著:不可能!
總之,只要沒有寫著,那麼讀者就可以獲得鎖。必須沒有讀者並且沒有寫著,寫者才能獲得鎖。正因為如此,讀寫鎖也成為「共享排他鎖(共享獨佔鎖)」,「多讀鎖」或者「單寫多讀鎖"。個人覺得,單寫多讀鎖,這個名稱最能反應其特性,也更容易記住。
(2)讀寫鎖的特性
上面的特性,總結為一句話就是:一次只有乙個執行緒可以占有寫模式的讀寫鎖, 但是可以有多個執行緒同時占有讀模式的讀寫鎖。
(3)讀寫鎖適用時機和例項
由於上面的特性,讀寫鎖適合於對資料結構的讀次數比寫次數多得多的情況。因為, 讀模式鎖定時可以共享, 以寫模式鎖住時意味著獨佔。
例項:
#include "stdafx.h"
#include #include #include #include long g = 0;
long temp = 0;
srwlock g_srw; // 定義讀寫鎖
critical_section g_cs; // 定義臨界區
#define thread_count 10 // 執行緒數
#define access_times 100000000 // 訪問共享變數的次數,增大其值,增加資料競爭發生的可能性
void __cdecl threadprocsrwwrite(void *para)
printf("sub thread finished\n");
_endthread(); // 可以省略,隱含會呼叫。
}void __cdecl threadprocsrwread(void *para)
printf("sub thread finished\n");
_endthread(); // 可以省略,隱含會呼叫。
}void __cdecl threadproccswrite(void *para)
printf("sub thread finished\n");
_endthread(); // 可以省略,隱含會呼叫。
} void __cdecl threadproccsread(void *para)
printf("sub thread finished\n");
_endthread(); // 可以省略,隱含會呼叫。
} int main(int argc, char* argv)
for(int i = 0;i < thread_count;i++)
waitforsingleobject(hthread[i],infinite);
end = clock();
t1 = end - start;
// 檢查結果
if (g != access_times)
printf("error result!\n");
g = 0;
// testing for critical section
initializecriticalsection(&g_cs); // 初始化臨界區
start = clock();
hthread[0] = (handle)_beginthread(threadproccswrite,0,null);
for(int i = 1;i < thread_count;i++)
for(int i = 0;i < thread_count;i++)
waitforsingleobject(hthread[i],infinite);
end = clock();
t2 = end - start;
deletecriticalsection(&g_cs); // 刪除臨界區
// 檢查結果
if (g != access_times*thread_count)
printf("error result!\n");
printf("timing rw: %ld\n", t1);
printf("timing cs: %ld\n", t2);
printf("timing cs/rw: %lf\n", t2/(double)t1);
}
上面這個例子,我建立10個執行緒,乙個執行緒寫,九個執行緒讀。分別使用臨界區和讀寫鎖,臨界區只是用來作為參考,我想證明一下讀寫鎖對於多讀少寫的情況下會有一些效能上的提公升。所以我希望是使用使用寫鎖(排他鎖)也用來進行讀保護,和使用讀鎖(共享鎖)來進行讀保護,希望的結果是對於讀保護使用讀鎖效率會有提公升。。。結果。。。居然和預料相反!難道讀鎖不是可以共享?效率不是更高?即上面**中threadprocsrwread()執行緒函式注釋的部分的比較。先mark一下,什麼時候找到合理的解釋了再更新!
歡迎補充!
讀寫鎖的特性
分類 多執行緒 windows 2011 11 09 21 01 406人閱讀收藏 舉報thread access testing null windows 資料結構 summary 分析讀寫鎖的特性,以windows為例。但是其實讀寫鎖最先是linux裡面有的,所以說,下面的分析,適用於linux...
讀寫鎖的特性
summary 分析讀寫鎖的特性,以windows為例。但是其實讀寫鎖最先是linux裡面有的,所以說,下面的分析,適用於linux和windows平台。wiki 1 讀寫鎖 讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進行讀訪問,寫者則需要對共享資源進行寫...
讀寫鎖 特性 介面及常見問題分析
適用的場景 少量寫的執行緒 大量讀的執行緒 讀寫鎖和互斥鎖很相似,但是讀寫鎖允許讀的並行 讀寫鎖的三種狀態 讀模式的加鎖狀態 寫模式的加鎖狀態 不加鎖的狀態 加鎖規則 一次只有乙個執行緒可以占有寫模式的讀寫鎖,不能同時寫,但能同時讀,即乙個執行流進行寫的時候,其他執行流既不能寫也不能讀,乙個執行流進...