flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么

這篇文章主要講解了“flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么”吧!

目前創(chuàng)新互聯(lián)已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、雅安服務(wù)器托管、綿陽服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計、塔什庫爾干塔吉克網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

首先以簡單的鏈表為案例,鏈表主要分為單向鏈表與雙向鏈表,單向鏈表的鏈表節(jié)點中只有一個鏈表指針,其指向后一個鏈表元素,而雙向鏈表節(jié)點中有兩個鏈表節(jié)點指針,其中Blink指向前一個鏈表節(jié)點Flink指向后一個節(jié)點,以雙向鏈表為例。

#include <ntifs.h>
#include <ntstrsafe.h>

/*
// 鏈表節(jié)點指針
typedef struct _LIST_ENTRY
{
  struct _LIST_ENTRY *Flink;   // 當(dāng)前節(jié)點的后一個節(jié)點
  struct _LIST_ENTRY *Blink;   // 當(dāng)前節(jié)點的前一個結(jié)點
}LIST_ENTRY, *PLIST_ENTRY;
*/

typedef struct _MyStruct
{
  ULONG x;
  ULONG y;
  LIST_ENTRY lpListEntry;
}MyStruct,*pMyStruct;

VOID UnDriver(PDRIVER_OBJECT driver)
{
  DbgPrint("驅(qū)動卸載成功 \n");
}

// By: LyShark
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
  DbgPrint("By:LyShark \n");
  DbgPrint("Email:me@lyshark.com \n");
  // 初始化頭節(jié)點
  LIST_ENTRY ListHeader = { 0 };
  InitializeListHead(&ListHeader);

  // 定義鏈表元素
  MyStruct testA = { 0 };
  MyStruct testB = { 0 };
  MyStruct testC = { 0 };

  testA.x = 100;
  testA.y = 200;

  testB.x = 1000;
  testB.y = 2000;

  testC.x = 10000;
  testC.y = 20000;

  // 分別插入節(jié)點到頭部和尾部
  InsertHeadList(&ListHeader, &testA.lpListEntry);
  InsertTailList(&ListHeader, &testB.lpListEntry);
  InsertTailList(&ListHeader, &testC.lpListEntry);

  // 節(jié)點不為空 則 移除一個節(jié)點
  if (IsListEmpty(&ListHeader) == FALSE)
  {
    RemoveEntryList(&testA.lpListEntry);
  }

  // 輸出鏈表數(shù)據(jù)
  PLIST_ENTRY pListEntry = NULL;
  pListEntry = ListHeader.Flink;

  while (pListEntry != &ListHeader)
  {
    // 計算出成員距離結(jié)構(gòu)體頂部內(nèi)存距離
    pMyStruct ptr = CONTAINING_RECORD(pListEntry, MyStruct, lpListEntry);
    DbgPrint("節(jié)點元素X = %d 節(jié)點元素Y = %d \n", ptr->x, ptr->y);

    // 得到下一個元素地址
    pListEntry = pListEntry->Flink;
  }

  Driver->DriverUnload = UnDriver;
  return STATUS_SUCCESS;
}

鏈表輸出效果如下:

flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么

如上所述,內(nèi)核鏈表讀寫時存在線程同步問題,解決多線程同步問題必須要用鎖,通常使用自旋鎖,自旋鎖是內(nèi)核中提供的一種高IRQL鎖,用同步以及獨占的方式訪問某個資源。

#include <ntifs.h>
#include <ntstrsafe.h>

/*
// 鏈表節(jié)點指針
typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *Flink;   // 當(dāng)前節(jié)點的后一個節(jié)點
struct _LIST_ENTRY *Blink;   // 當(dāng)前節(jié)點的前一個結(jié)點
}LIST_ENTRY, *PLIST_ENTRY;
*/

typedef struct _MyStruct
{
	ULONG x;
	ULONG y;
	LIST_ENTRY lpListEntry;
}MyStruct, *pMyStruct;

// 定義全局鏈表和全局鎖
LIST_ENTRY my_list_header;
KSPIN_LOCK my_list_lock;

// 初始化
void Init()
{
	InitializeListHead(&my_list_header);
	KeInitializeSpinLock(&my_list_lock);
}

// 函數(shù)內(nèi)使用鎖
void function_ins()
{
	KIRQL Irql;

	// 加鎖
	KeAcquireSpinLock(&my_list_lock, &Irql);

	DbgPrint("鎖內(nèi)部執(zhí)行 \n");

	// 釋放鎖
	KeReleaseSpinLock(&my_list_lock, Irql);
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("驅(qū)動卸載成功 \n");
}

// By: LyShark
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("By:LyShark \n");
	DbgPrint("Email:me@lyshark.com \n");

	// 初始化鏈表
	Init();

	// 分配鏈表空間
	pMyStruct testA = (pMyStruct)ExAllocatePool(NonPagedPoolExecute, sizeof(pMyStruct));
	pMyStruct testB = (pMyStruct)ExAllocatePool(NonPagedPoolExecute, sizeof(pMyStruct));

	// 賦值
	testA->x = 100;
	testA->y = 200;

	testB->x = 1000;
	testB->y = 2000;

	// 向全局鏈表中插入數(shù)據(jù)
	if (NULL != testA && NULL != testB)
	{
		ExInterlockedInsertHeadList(&my_list_header, (PLIST_ENTRY)&testA->lpListEntry, &my_list_lock);
		ExInterlockedInsertTailList(&my_list_header, (PLIST_ENTRY)&testB->lpListEntry, &my_list_lock);
	}

	function_ins();

	// 移除節(jié)點A并放入到remove_entry中
	PLIST_ENTRY remove_entry = ExInterlockedRemoveHeadList(&testA->lpListEntry, &my_list_lock);

	// 輸出鏈表數(shù)據(jù)
	while (remove_entry != &my_list_header)
	{
		// 計算出成員距離結(jié)構(gòu)體頂部內(nèi)存距離
		pMyStruct ptr = CONTAINING_RECORD(remove_entry, MyStruct, lpListEntry);
		DbgPrint("節(jié)點元素X = %d 節(jié)點元素Y = %d \n", ptr->x, ptr->y);

		// 得到下一個元素地址
		remove_entry = remove_entry->Flink;
	}

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

加鎖后執(zhí)行效果如下:

flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么

感謝各位的閱讀,以上就是“flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

網(wǎng)站題目:flink內(nèi)核中的自旋鎖結(jié)構(gòu)是什么
當(dāng)前URL:http://muchs.cn/article20/jojsjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、定制開發(fā)、網(wǎng)站排名、用戶體驗外貿(mào)網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)