spin lock自旋锁 双链表操作(多线程安全)(Ring0)
通过spin lock自旋锁 ,为每个链表都定义并初始化一个锁,在需要向该链表插入或移除节点时不使用前面介绍的普通函数,而是使用如下方法:
ExInterlockedInsertHeadList(&linkListHead, &pData->ListEntry, &spin_lock);
//ExInterlockedInsertTailList(&linkListHead, &pData->ListEntry, &spin_lock);
ExInterlockedRemoveHeadList(&linkListHead, &spin_lock);
此时在向链表中插入或移除节点时会自动调用关联的锁进行加锁操作,有效地保证了多线程安全性。
#include <ntifs.h> typedef struct _ITEM_ {
ULONG ItemData;
LIST_ENTRY ItemEntry;
}ITEM, *PITEM; VOID SeCreateAtomLock();
VOID RemoveThreadProcedure(PVOID ParameterData);
VOID InsertThreadProcedure(PVOID ParameterData);
VOID DriverUnload(PDRIVER_OBJECT DriverObject); //bp KAtomLock!DriverEntry
LIST_ENTRY __ListHead;
KSPIN_LOCK __SpinLock;
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL; DriverObject->DriverUnload = DriverUnload; //初始化链表
InitializeListHead(&__ListHead);
KeInitializeSpinLock(&__SpinLock);
SeCreateAtomLock(); while (!IsListEmpty(&__ListHead))
{
PLIST_ENTRY ListEntry = RemoveTailList(&__ListHead);
PITEM v1 = CONTAINING_RECORD(ListEntry,
ITEM,
ItemEntry);
KdPrint(("%d\n",v1->ItemData));
ExFreePool(v1);
}
return Status;
}
VOID SeCreateAtomLock()
{
HANDLE ThreadHandle[] = { };
ULONG i = ;
PVOID ThreadObject[] = { };
PsCreateSystemThread(&ThreadHandle[], , NULL, NULL, NULL, InsertThreadProcedure,NULL);
PsCreateSystemThread(&ThreadHandle[], , NULL, NULL, NULL, RemoveThreadProcedure,NULL);
for (i = ; i < ; i++)
{
ObReferenceObjectByHandle(ThreadHandle[i], , NULL, KernelMode, &ThreadObject[i], NULL);
}
KeWaitForMultipleObjects(, ThreadObject, WaitAll, Executive, KernelMode, FALSE, NULL, NULL);
for (i = ; i < ; i++)
{
ObDereferenceObject(ThreadObject[i]);
ZwClose(ThreadHandle[i]);
ThreadHandle[i] = NULL;
}
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("DriverUnload()\r\n");
} VOID InsertThreadProcedure(PVOID ParameterData)
{
PITEM Item;
int Count = ; for (Count = ; Count <= ; Count += )
{
DbgPrint("InsertThreadProcedure()\r\n");
Item = (PITEM)
ExAllocatePool(PagedPool, sizeof(ITEM)); //分页内存
Item->ItemData = Count;
//ExInterlockedInsertTailList 插入双向链表互锁操作
ExInterlockedInsertHeadList(&__ListHead, &Item->ItemEntry,&__SpinLock);
}
PsTerminateSystemThread(STATUS_SUCCESS); } VOID RemoveThreadProcedure(PVOID ParameterData)
{ int Count = ;
for (Count = ; Count <= ; Count += )
{
DbgPrint("RemoveThreadProcedure()\r\n");
PLIST_ENTRY ListEntry = ExInterlockedRemoveHeadList(&__ListHead,&__SpinLock);
PITEM v1 = CONTAINING_RECORD(ListEntry,
ITEM,
ItemEntry);
ExFreePool(v1);
}
PsTerminateSystemThread(STATUS_SUCCESS); }
spin lock自旋锁 双链表操作(多线程安全)(Ring0)的更多相关文章
- 多目标遗传算法 ------ NSGA-II (部分源码解析)辅助变量 双链表操作 list.c
/* A custom doubly linked list implemenation */ # include <stdio.h> # include <stdlib.h> ...
- Synchronized和Lock, 以及自旋锁 Spin Lock, Ticket Spin Lock, MCS Spin Lock, CLH Spin Lock
Synchronized和Lock synchronized是一个关键字, Lock是一个接口, 对应有多种实现. 使用synchronized进行同步和使用Lock进行同步的区别 使用synchro ...
- 自旋锁Spin lock与互斥锁Mutex的区别
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
- APUE学习笔记——11 线程同步、互斥锁、自旋锁、条件变量
线程同步 同属于一个进程的不同线程是共享内存的,因而在执行过程中需要考虑数据的一致性. 假设:进程有一变量i=0,线程A执行i++,线程B执行i++,那么最终i的取值是多少呢?似乎一定 ...
- 自旋锁(Spin Lock)
转载请您注明出处: http://www.cnblogs.com/lsh123/p/7400625.html 0x01 自旋锁简介 自旋锁也是一种同步机制,它能保证某个资源只能被一个线程所拥有, ...
- Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
Optimistic concurrency control https://en.wikipedia.org/wiki/Optimistic_concurrency_control Optimist ...
- 【APUE】信号量、互斥体和自旋锁
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html http://blog.chinaunix.net/uid-205 ...
- Linux内核的同步机制---自旋锁
自旋锁的思考:http://bbs.chinaunix.net/thread-2333160-1-1.html 近期在看宋宝华的<设备驱动开发具体解释>第二版.看到自旋锁的部分,有些疑惑. ...
- 转:自旋锁(spinlock)
自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名. 由于 ...
随机推荐
- 雷林鹏分享:jQuery EasyUI 数据网格 - 添加分页组件
jQuery EasyUI 数据网格 - 添加分页组件 本实例演示如何从服务器端加载数据,如何添加分页组件(pagination)到数据网格(datagrid). 创建数据网格(DataGrid) 为 ...
- 雷林鹏分享:jQuery EasyUI 树形菜单 - 创建复杂树形网格
jQuery EasyUI 树形菜单 - 创建复杂树形网格 树形网格(TreeGrid)可以展示有限空间上带有多列和复杂数据电子表格.本教程将演示如何将表格数据排列在分割的网格和多行表头中,以便组织共 ...
- 20181013xlVba成绩报表优化
Public Sub 成绩报表优化() Application.ScreenUpdating = False Application.DisplayAlerts = False Application ...
- stark组件base.html
stark 组件基础页面base.html 文件 base.html 1. base.html 页面是 : stark组件增,删,改,查页面的公共部分,如头部导航栏,左侧的用户权限列表栏等. 2. b ...
- Date类型与String类型的相关问题
今天完成boss交代的任务时,遇到Date类型与String类型的相关问题,参考了网上的一些例子,并且自己写了demo,现在记录下了总结一下: (一)判断一个字符串是不是合法的日期格式 public ...
- 6月13 ThinkPHP框架基础
ThinkPHP 一.php框架基础介绍 真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维 ...
- Oracle PL/SQL异常、存储过程和触发器
一.异常 1.处理异常 (1)除数不为0 declare b number; begin b:; exception when zero_divide then dbms_output.put_lin ...
- Linux在shell中输入历史命令
在Linux的shell中,经常输入的命令有很多雷同,甚至是一样的, 如果是长命令,再次敲一遍效率真的是很低, 不过可以通过Ctl+r, 查找history中以前输入的命令,很是好用. 按Ctrl+ ...
- 一、SQLite学习
由于公司业务拓展,需要开发一个基于ASP.NET Core2.0+AdminLTE架构的后台管理系统,数据库选择方面,选择了使用SQLite轻便. SQLite:一个软件库,实现自给自足,无服务器,零 ...
- RocketMQ安装教程
1.下载 http://mirror.bit.edu.cn/apache/rocketmq/ 2.安装 .tar.gz cd alibaba-rocketmq/bin chmod u+x * 3.配置 ...