通过spin lock自旋锁 ,为每个链表都定义并初始化一个锁,在需要向该链表插入或移除节点时不使用前面介绍的普通函数,而是使用如下方法:
ExInterlockedInsertHeadList(&linkListHead, &pData->ListEntry, &spin_lock);
//ExInterlockedInsertTailList(&linkListHead, &pData->ListEntry, &spin_lock);
ExInterlockedRemoveHeadList(&linkListHead, &spin_lock);
此时在向链表中插入或移除节点时会自动调用关联的锁进行加锁操作,有效地保证了多线程安全性。
1 #include <ntifs.h> 2 3 4 typedef struct _ITEM_ { 5 ULONG ItemData; 6 LIST_ENTRY ItemEntry; 7 }ITEM, *PITEM; 8 9 VOID SeCreateAtomLock(); 10 VOID RemoveThreadProcedure(PVOID ParameterData); 11 VOID InsertThreadProcedure(PVOID ParameterData); 12 VOID DriverUnload(PDRIVER_OBJECT DriverObject); 13 14 //bp KAtomLock!DriverEntry 15 LIST_ENTRY __ListHead; 16 KSPIN_LOCK __SpinLock; 17 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath) 18 { 19 NTSTATUS Status = STATUS_SUCCESS; 20 PDEVICE_OBJECT DeviceObject = NULL; 21 22 DriverObject->DriverUnload = DriverUnload; 23 24 //初始化链表 25 InitializeListHead(&__ListHead); 26 KeInitializeSpinLock(&__SpinLock); 27 SeCreateAtomLock(); 28 29 while (!IsListEmpty(&__ListHead)) 30 { 31 PLIST_ENTRY ListEntry = RemoveTailList(&__ListHead); 32 PITEM v1 = CONTAINING_RECORD(ListEntry, 33 ITEM, 34 ItemEntry); 35 KdPrint(("%d ",v1->ItemData)); 36 ExFreePool(v1); 37 } 38 return Status; 39 } 40 VOID SeCreateAtomLock() 41 { 42 HANDLE ThreadHandle[2] = { 0 }; 43 ULONG i = 0; 44 PVOID ThreadObject[2] = { 0 }; 45 PsCreateSystemThread(&ThreadHandle[0], 0, NULL, NULL, NULL, InsertThreadProcedure,NULL); 46 PsCreateSystemThread(&ThreadHandle[1], 0, NULL, NULL, NULL, RemoveThreadProcedure,NULL); 47 for (i = 0; i < 2; i++) 48 { 49 ObReferenceObjectByHandle(ThreadHandle[i], 0, NULL, KernelMode, &ThreadObject[i], NULL); 50 } 51 KeWaitForMultipleObjects(2, ThreadObject, WaitAll, Executive, KernelMode, FALSE, NULL, NULL); 52 for (i = 0; i < 2; i++) 53 { 54 ObDereferenceObject(ThreadObject[i]); 55 ZwClose(ThreadHandle[i]); 56 ThreadHandle[i] = NULL; 57 } 58 } 59 VOID DriverUnload(PDRIVER_OBJECT DriverObject) 60 { 61 DbgPrint("DriverUnload() "); 62 } 63 64 VOID InsertThreadProcedure(PVOID ParameterData) 65 { 66 PITEM Item; 67 int Count = 0; 68 69 70 for (Count = 1; Count <= 20; Count += 1) 71 { 72 DbgPrint("InsertThreadProcedure() "); 73 Item = (PITEM) 74 ExAllocatePool(PagedPool, sizeof(ITEM)); //分页内存 75 Item->ItemData = Count; 76 //ExInterlockedInsertTailList 插入双向链表互锁操作 77 ExInterlockedInsertHeadList(&__ListHead, &Item->ItemEntry,&__SpinLock); 78 } 79 PsTerminateSystemThread(STATUS_SUCCESS); 80 81 } 82 83 VOID RemoveThreadProcedure(PVOID ParameterData) 84 { 85 86 int Count = 0; 87 for (Count = 1; Count <= 10; Count += 1) 88 { 89 DbgPrint("RemoveThreadProcedure() "); 90 PLIST_ENTRY ListEntry = ExInterlockedRemoveHeadList(&__ListHead,&__SpinLock); 91 PITEM v1 = CONTAINING_RECORD(ListEntry, 92 ITEM, 93 ItemEntry); 94 ExFreePool(v1); 95 } 96 PsTerminateSystemThread(STATUS_SUCCESS); 97 98 }