Windows事件等待学习笔记(一)—— 临界区自旋锁
Windows事件等待学习笔记(一)—— 临界区&自旋锁
- 基础知识
- 演示代码
- 案例一
- 案例二
- LOCK
- 单行代码原子操作
- 多行代码原子操作
- 临界区
- 演示代码
- 手动实现
- 自旋锁
- 分析 KeAcquireSpinLockAtDpcLevel
- 总结
基础知识
并发:是指多个线程在同时执行
- 单核(是分时执行,不是真正的同时)
- 多核(在某一个时刻,会同时有多个线程再执行)
同步:则是保证在并发执行的环境中各个线程可以有序的执行
演示代码
注意:如果线程中的代码只对局部变量进行访问,就不存在并发的问题;只有当访问全局变量的时候,才需要关注并发的问题
案例一
DWORD dwVal = 0; //全局变量线程中的代码:dwVal++; //只有一行 安全吗?
答案:
dwVal++; 对应的汇编代码:mov eax,[0x12345678]add eax,1 //当第一个线程执行到这里时,产生了线程切换的话//第二个线程也执行到这里时,将会出现逻辑错误mov [0x12345678],eax
案例二
当将案例一的三行汇编代码改为一行时:
INC DWORD PTR DS:[0x12345678] //一行汇编指令,安全吗?
答案:若当前系统为单核时,安全;但如果当前CPU为多核时,不安全(两个核有可能同时执行一行指令)
解决方案:改为LOCK INC DWORD PTR DS:[0x12345678]
LOCK
描述:在多核CPU的情况下,保证只有一个CPU能访问带有LOCK指令内存
可以带LOCK前缀的指令:
BT, BTS, BTR, BTC (mem, reg/imm)
XCHG, XADD (reg, mem / mem, reg)
ADD, OR, ADC, SBB (mem, reg/imm)
AND, SUB, XOR (mem, reg/imm)
NOT, NEG, INC, DEC (mem)
单行代码原子操作
原子操作相关API:
InterlockedIncrement InterlockedExchangeAdd
InterlockedDecrement InterlockedFlushSList
InterlockedExchange InterlockedPopEntrySList
InterlockedCompareExchange InterlockedPushEntrySList
InterlockedIncrement 反汇编:
多行代码原子操作
关键代码A //N行代码要求原子操作
关键代码B //单独加LOCK可以吗?
关键代码C
.......
答案:不行,试想一下,当第一个线程执行到关键代码B,第二个线程就执行完关键代码A时,此时虽然第二个线程无法执行关键代码B,但却有可能会先执行关键代码C
解决方案:临界区
临界区
描述:一次只允许一个线程进入直到离开
实现思路:加锁(全局变量)
演示代码
DWORD dwFlag = 0; //实现临界区的方式就是加锁//锁:全局变量 进去加一 出去减一if(dwFlag == 0) //进入临界区
{ dwFlag = 1 .....................dwFlag = 0 //离开临界区
}
问题:上述演示代码安全吗?
答案:仍不安全,当第一个线程通过if判断并进入if内部,但还未来得及执行dwFlag=1时,第二个线程也有可能通过if判断从而进入if语句内部
手动实现
进入临界区:
Lab:mov eax,1lock xadd [Flag],eaxcmp eax,0jz endLabdec [Flag]//线程等待Sleep..
endLab:ret
离开临界区
lock dec [Flag]
自旋锁
小提示:单核和多核虽然使用的是同一份内核文件,但里面的代码是有区别的
单核 ntoskrnl.exe 反汇编:
多核 ntoskrnl.exe 反汇编:
分析 KeAcquireSpinLockAtDpcLevel
多核:
单核:
总结
- 自旋锁只对多核有意义
(查看不同版本的KeAcquireSpinLockAtDpcLevel函数) - 自旋锁与临界区、事件、互斥体一样,都是一种同步机制,都可以让当前线程处于等待状态,区别在于自旋锁不用切换线程
Windows事件等待学习笔记(一)—— 临界区自旋锁相关推荐
- Windows事件等待学习笔记(二)—— 线程等待与唤醒
Windows事件等待学习笔记(二)-- 线程等待与唤醒 要点回顾 等待与唤醒机制 可等待对象 可等待对象的差异 线程与等待对象 一个线程等待一个对象 实验 第一步:编译并运行以下代码 第二步:在Wi ...
- Windows事件等待学习笔记(四)—— 事件信号量互斥体
Windows事件等待学习笔记(四)-- 事件&信号量&互斥体 要点回顾 事件 实验:验证SignalState 第一步:编译并运行以下代码 第二步:观察结果 第三步:修改代码并执行 ...
- Windows事件等待学习笔记(三)—— WaitForSingleObject函数分析
Windows事件等待学习笔记(三)-- WaitForSingleObject函数分析 要点回顾 WaitForSingleObject NtWaitForSingleObject KeWaitFo ...
- Windows驱动开发学习笔记(七)—— 多核同步内核重载
Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...
- Windows phone 8 学习笔记(5) 图块与通知
基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认图块,还可以有若干个次要图块.另外,通知与图块的关系比较密切,我们 ...
- windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互
windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互 前面两篇学习笔记分别介绍了IRP和IO_STACK_LOCATION,整个设备栈来处理这个IRP,但是每个设 ...
- Windows phone 8 学习笔记(8) 定位地图导航
Windows phone 8 学习笔记(8) 定位地图导航 原文:Windows phone 8 学习笔记(8) 定位地图导航 Windows phone 8 已经不使用自家的bing地图,新地图控 ...
- Windows消息机制学习笔记(三)—— 消息的接收与分发
Windows消息机制学习笔记(三)-- 消息的接收与分发 要点回顾 消息循环 消息队列 消息的接收 GetMessage 实验1:理解GetMessage 第一步:编译并运行程序A 第二步:编译并运 ...
- Windows消息机制学习笔记(一)—— 消息队列
Windows消息机制学习笔记(一)-- 消息队列 基本概念 实验一:使用代码画出最简单窗口 第一步:编译并运行以下代码 第二步:查看运行结果 第三步:使用其它窗口对其进行覆盖,观察效果 总结 消息队 ...
最新文章
- SD-WAN — Overview
- (转)linux运行tomcat时JRE_HOME显示不对怎么办?
- 数学奥赛用不用计算机,报考自招必看!五大学科竞赛利弊详解,到底哪科最适合你?...
- AbstractListView源码分析8
- Microsoft AJAX Client Library规范的实例
- python内置对象是什么_Python内置对象类型之数字类型
- 【Python】Matplotlib绘制三维散点图
- java中的原型模式_java中的原型模式理解
- python27缺少dll的解决
- Java的静态数组和动态数组
- java long 转换成 Date
- IT6801FN中文版
- 区块链游戏:何为虚拟?何为现实?
- ECS设置时区与时间
- 计算机瞬间关闭所有程序的方法,Win10如何设置关机时快速关闭所有程序
- 微信锁屏密码怎么设置
- 【学习笔记】H5性能测试
- 【NOIP模拟赛】小猫爬山
- DraftSight:Linux下完美的AutoCAD
- Spark学习总结以及问题
热门文章
- CV之FDFA:利用MTCNN的脚本实现对LFW数据集进行FD人脸检测和FA人脸校准
- Python语言学习:Python常用自带库(imageio、pickle)简介、使用方法之详细攻略
- MAT之SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题
- 5.1 Tensorflow:图与模型的加载与存储
- Android插件化开发之解决OpenAtlas组件在宿主的注冊问题
- css 控制li点与文字的距离
- 飘逸的python - 鲜为人知的参数
- 国际域名也将列入监管范畴(本文转载自【易名中国】)
- TCP传输的单个报文最大字节(MSS和MTU)
- 如何用jlink+jflash烧写stm32f103CB的option bytes 和程序