1.原子訪問
原子訪問指的是一個線程在訪問某個資源的同時能夠保證沒有其他線程會在同一時刻訪問同一資源。相關的Interlocker函數有如下:
1)InterlockedExchangeAdd
2)InterlockedExchangeAdd64
3)InterlockedIncrement
4)InterlockedExchange
5)InterlockedExchange64
........
Interlocker函數的工作原理: 會在總線上維護一個硬件信號,這個信號會阻止其它CPU訪問同一個內存地址。
Interlocker函數的優點: 執行速度快,調用一次Interlocker函數通常只佔用幾個CPU週期(通常小於50),而且不需要在用戶模式和內核模式之間進行切換(這個切換通常需佔用1000個CPU週期以上)
應用場景: 實現旋轉鎖;當多個進程需對訪問一個共享內存段中的值進行同步時,也可使用。
2.高速緩存行
高速緩存行是以對齊到32字節、64字節或128字節( 取決於CPU)爲邊界,將應用程序所訪問的一組相鄰字節進行緩存,以提高性能。爲解決CPU間讀取"髒"數據的問題,採用"觀察者"的設計模式,即某個CPU修改高速緩存中的某個字節時,機器中其它的CPU會收到通知,並使自己的高速緩存行作廢,重新訪問內存來填充自己的高速緩存行。
應用場景: 應根據高速緩存行的大小來將應用程序的相類似的數據組織在一起,並將數據與緩存行的邊界對齊。把只讀數據(或不經常讀的數據)與可讀寫數據分別存放,還應該把差不多同一時間訪問的數據組織在一起。
#define CACHE_ALIGN 64
struct __declspec(align(CACHE_ALIGN)) CUSTINFO
{
DWORD dwCustomerID; //mostly read-only
wchar_t szname[100]; //mostly read-only
__declspec(align(CACHE_ALIGN))
int nBalanceDue; //Read-write
FILETIME ftLastorderDate; //Read-write
};
3.高級線程同步
這種機制實現既能讓線程等待共享資源的訪問權,又不會浪費CPU時間。 大致原理: 當線程想訪問一個共享資源或想要得到一些特殊事件的通知時,線程必須調用操作系統的一個函數(例如: WaitForSingedObject),並將線程想要等待的東西作爲參數傳入,由操作系統來記住線程想要訪問什麼資源或想得到什麼通知。
如果無法取得對共享資源的訪問權(可能另一個線程正在佔用),或者特殊事件尚未觸發,那麼系統會將線程切換到等待狀態,讓線程變得不可調度。
如果操作系統檢測到共享資源已經可供使用了,或者特殊事件觸發了,線程調用的等待函數將返回,線程變成可調度的狀態。
4.關鍵段
關鍵段是一小段代碼,它在執行之前需要獨佔對一些共享資源的訪問權。
使用示例:
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
EnterCriticalSection(&cs);
//共享資源
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs);
關鍵段在內部也使用Interlocker函數,執行速度快,但是無法用來在多個進程之間的同步,只能是用於同一進程內的線程進行同步,屬於輕量級的。