扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章主要讲解了“flink内核中的自旋锁结构是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“flink内核中的自旋锁结构是什么”吧!
目前创新互联已为上千余家的企业提供了网站建设、域名、雅安服务器托管、绵阳服务器托管、企业网站设计、塔什库尔干塔吉克网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
首先以简单的链表为案例,链表主要分为单向链表与双向链表,单向链表的链表节点中只有一个链表指针,其指向后一个链表元素,而双向链表节点中有两个链表节点指针,其中Blink
指向前一个链表节点Flink
指向后一个节点,以双向链表为例。
#include#include /* // 链表节点指针 typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; // 当前节点的后一个节点 struct _LIST_ENTRY *Blink; // 当前节点的前一个结点 }LIST_ENTRY, *PLIST_ENTRY; */ typedef struct _MyStruct { ULONG x; ULONG y; LIST_ENTRY lpListEntry; }MyStruct,*pMyStruct; VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驱动卸载成功 \n"); } // By: LyShark NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("By:LyShark \n"); DbgPrint("Email:me@lyshark.com \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; // 分别插入节点到头部和尾部 InsertHeadList(&ListHeader, &testA.lpListEntry); InsertTailList(&ListHeader, &testB.lpListEntry); InsertTailList(&ListHeader, &testC.lpListEntry); // 节点不为空 则 移除一个节点 if (IsListEmpty(&ListHeader) == FALSE) { RemoveEntryList(&testA.lpListEntry); } // 输出链表数据 PLIST_ENTRY pListEntry = NULL; pListEntry = ListHeader.Flink; while (pListEntry != &ListHeader) { // 计算出成员距离结构体顶部内存距离 pMyStruct ptr = CONTAINING_RECORD(pListEntry, MyStruct, lpListEntry); DbgPrint("节点元素X = %d 节点元素Y = %d \n", ptr->x, ptr->y); // 得到下一个元素地址 pListEntry = pListEntry->Flink; } Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
链表输出效果如下:
如上所述,内核链表读写时存在线程同步问题,解决多线程同步问题必须要用锁,通常使用自旋锁,自旋锁是内核中提供的一种高IRQL锁,用同步以及独占的方式访问某个资源。
#include#include /* // 链表节点指针 typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; // 当前节点的后一个节点 struct _LIST_ENTRY *Blink; // 当前节点的前一个结点 }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); } // 函数内使用锁 void function_ins() { KIRQL Irql; // 加锁 KeAcquireSpinLock(&my_list_lock, &Irql); DbgPrint("锁内部执行 \n"); // 释放锁 KeReleaseSpinLock(&my_list_lock, Irql); } VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驱动卸载成功 \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; // 向全局链表中插入数据 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(); // 移除节点A并放入到remove_entry中 PLIST_ENTRY remove_entry = ExInterlockedRemoveHeadList(&testA->lpListEntry, &my_list_lock); // 输出链表数据 while (remove_entry != &my_list_header) { // 计算出成员距离结构体顶部内存距离 pMyStruct ptr = CONTAINING_RECORD(remove_entry, MyStruct, lpListEntry); DbgPrint("节点元素X = %d 节点元素Y = %d \n", ptr->x, ptr->y); // 得到下一个元素地址 remove_entry = remove_entry->Flink; } Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
加锁后执行效果如下:
感谢各位的阅读,以上就是“flink内核中的自旋锁结构是什么”的内容了,经过本文的学习后,相信大家对flink内核中的自旋锁结构是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流