1. 程式人生 > >Windows核心程式設計基礎篇之使用自旋鎖

Windows核心程式設計基礎篇之使用自旋鎖

   連結串列之類的結構總是涉及多執行緒,這時候就要用到使用鎖。

    當然在處理臨界區的時候,這個是必須要考慮的呀。

   在驅動開發的程式碼中,大多是在於多執行緒執行環境的。

    下面將介紹使用簡單的自旋鎖

    如下的程式碼將初始化一個自旋鎖:

KSPIN_ my_Spin_Lock;
KeInitializeSpinLock(&my_Spin_Lock);
     KeInitializeSpinLock 函式沒有返回值。

KeAccquireSpinLock KeReleaseSpinLock 之間的程式碼是隻有單執行緒執行的,其他的現成會停留在KeAccquireSpinLock

等候,直到KeReleaseSpinLock被呼叫。KIRQL是一箇中斷級。

void MySafeFunction()
{
	KSPIN_LOCK my_spin_lock;
	KIRQL irql;
	KeInitialiezeSpinLock(&my_spin_lock);
	KeAccquireSpinLock(&my_spin_lock, &irql);
	
	//----do something
	
	KeReleaseSpinLock(&my_spin_lock, &irql);
}
    (怎麼和 函式:waitforsingleObject
的使用非常相似呢?大笑好事兒)

     在堆疊中,每個執行緒都會重新初始化一個鎖,只有所有的執行緒共用一個鎖,鎖才意義。鎖一般不會定義成區域性變數。
      LIT_ENTRY 有一系列的操作。這些操作並不需要使用者自己呼叫獲取與釋放鎖,只需要為每個連結串列定並初始化一個鎖即可。

LIST_ENTRY my_List_Head;	///---連結串列頭
KSPIN_LOCK my_spin_lock;	///--連結串列的鎖

///--連結串列初始化函式
void MyFileInfoInit()
{
	InitializeListHead(&my_List_Head);
	KeAccquireSpinLock(&my_spin_lock);
}
    初始化就這樣簡單的完成了。接下來就可以採用加鎖的操作來代替普通的操作啦:

////-----插入一個節點。

    普通操作程式碼:

InsertHeadList(&my_spin_lock, (PLIST_ENTRY)&my_File_Info);
    換成加鎖的程式碼如下
ExIntertlockedInsetHeadList(
	&my_List_Head,
	(PLIST_ENTRY)&my_File_Info,
	&my_spin_lock );
      不同在於增加了  KSPIN_LOCK 的指標作為引數。在函式  ExIntertInsertHeadList 中,會自動使用 這個KSPIN_LOCK進行加鎖。類似的還有一個加鎖函式 Remove 函式。用來移除一個節點:

///------移除節點程式碼

my_file_info  = ExInterlockedRemoveHeadList(
&my_list_head,
&my_list_lock );
-----------------------  摘自<[天書夜讀-從彙編到Windows核心程式設計]>