最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C語言內(nèi)核中的自旋鎖結(jié)構(gòu)

 更新時(shí)間:2022年09月29日 15:35:50   作者:lyshark  
自旋鎖是內(nèi)核中提供的一種高IRQL鎖,用同步以及獨(dú)占的方式訪問某個(gè)資源。自旋鎖是為了解決內(nèi)核鏈表讀寫時(shí)存在線程同步問題。本文將講解一下自旋鎖的簡(jiǎn)單應(yīng)用,感興趣的可以了解一下

提到自旋鎖那就必須要說鏈表,在上一篇《驅(qū)動(dòng)開發(fā):內(nèi)核中的鏈表與結(jié)構(gòu)體》文章中簡(jiǎn)單實(shí)用鏈表結(jié)構(gòu)來存儲(chǔ)進(jìn)程信息列表,相信讀者應(yīng)該已經(jīng)理解了內(nèi)核鏈表的基本使用,本篇文章將講解自旋鎖的簡(jiǎn)單應(yīng)用,自旋鎖是為了解決內(nèi)核鏈表讀寫時(shí)存在線程同步問題,解決多線程同步問題必須要用鎖,通常使用自旋鎖,自旋鎖是內(nèi)核中提供的一種高IRQL鎖,用同步以及獨(dú)占的方式訪問某個(gè)資源。

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

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

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

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

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

// By: LyShark
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
  DbgPrint("By:LyShark \n");
  DbgPrint("Email:me@lyshark.com \n");
  // 初始化頭節(jié)點(diǎn)
  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é)點(diǎn)到頭部和尾部
  InsertHeadList(&ListHeader, &testA.lpListEntry);
  InsertTailList(&ListHeader, &testB.lpListEntry);
  InsertTailList(&ListHeader, &testC.lpListEntry);

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

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

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

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

  Driver->DriverUnload = UnDriver;
  return STATUS_SUCCESS;
}

鏈表輸出效果如下:

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

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

/*
// 鏈表節(jié)點(diǎn)指針
typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *Flink;   // 當(dāng)前節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn)
struct _LIST_ENTRY *Blink;   // 當(dāng)前節(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)
}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ū)動(dòng)卸載成功 \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é)點(diǎn)A并放入到remove_entry中
	PLIST_ENTRY remove_entry = ExInterlockedRemoveHeadList(&testA->lpListEntry, &my_list_lock);

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

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

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

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

到此這篇關(guān)于詳解C語言內(nèi)核中的自旋鎖結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)C語言內(nèi)核 自旋鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言關(guān)鍵字之a(chǎn)uto register詳解

    C語言關(guān)鍵字之a(chǎn)uto register詳解

    這篇文章主要為大家介紹了C語言關(guān)鍵字之a(chǎn)uto register,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 詳解C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配

    詳解C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配

    內(nèi)存分配 (Memory Allocation) 是指為計(jì)算機(jī)程序或服務(wù)分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個(gè)過程,本文主要介紹了C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配,感興趣的同學(xué)可以參考閱讀
    2023-06-06
  • C/C++ 開發(fā)神器CLion使用入門超詳細(xì)教程

    C/C++ 開發(fā)神器CLion使用入門超詳細(xì)教程

    這篇文章主要介紹了C/C++ 開發(fā)神器CLion使用入門超詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 解析結(jié)構(gòu)體的定義及使用詳解

    解析結(jié)構(gòu)體的定義及使用詳解

    本篇文章是對(duì)結(jié)構(gòu)體的定義以及使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++錯(cuò)誤信息處理的常見方法及函數(shù)

    C/C++錯(cuò)誤信息處理的常見方法及函數(shù)

    C/C++是兩種廣泛使用的編程語言,特別是在系統(tǒng)編程、嵌入式開發(fā)以及高性能計(jì)算領(lǐng)域,這篇文章主要介紹了C/C++錯(cuò)誤信息處理的常見方法及函數(shù),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • C語言字符串轉(zhuǎn)換為Python字符串的方法

    C語言字符串轉(zhuǎn)換為Python字符串的方法

    這篇文章主要介紹了C語言字符串轉(zhuǎn)換為Python字符串的方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • OpenCV圖像幾何變換之透視變換

    OpenCV圖像幾何變換之透視變換

    這篇文章主要為大家詳細(xì)介紹了OpenCV圖像幾何變換之透視變換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • C++ OpenCV實(shí)戰(zhàn)之形狀識(shí)別

    C++ OpenCV實(shí)戰(zhàn)之形狀識(shí)別

    本案例通過使用OpenCV中的approxPolyDP進(jìn)行多邊形近似,進(jìn)而進(jìn)行基礎(chǔ)形狀識(shí)別(圓、三角形、矩形、星形…),快跟隨小編一起動(dòng)手嘗試一下
    2022-07-07
  • C++ find函數(shù)及用法小結(jié)

    C++ find函數(shù)及用法小結(jié)

    string類的find()函數(shù)用于在字符串中查找字符或子串,返回第一個(gè)匹配的位置,C++中的find()函數(shù)有多種用法,本文通過實(shí)例代碼給大家詳細(xì)講解,感興趣的朋友一起看看吧
    2023-12-12
  • Matlab實(shí)現(xiàn)三維投影繪制的示例代碼

    Matlab實(shí)現(xiàn)三維投影繪制的示例代碼

    這篇文章系小編為大家?guī)砹艘粋€(gè)三維投影繪制函數(shù)(三視圖繪制),函數(shù)支持三維曲線、曲面、三維多邊形、參數(shù)方程曲線、參數(shù)方程曲面的投影繪制,需要的可以參考一下
    2022-08-08

最新評(píng)論

诸暨市| 德州市| 乌兰浩特市| 大厂| 靖安县| 安溪县| 孝义市| 巩留县| 太白县| 塘沽区| 东源县| 连城县| 葵青区| 汶上县| 乌兰浩特市| 太仆寺旗| 息烽县| 乌拉特前旗| 准格尔旗| 若羌县| 收藏| 菏泽市| 廉江市| 浮山县| 婺源县| 泗洪县| 平远县| 永新县| 招远市| 舟山市| 高碑店市| 常山县| 高雄县| 昌江| 五指山市| 和田县| 团风县| 天等县| 舒兰市| 安新县| 邹平县|