Windows事件等待学习笔记(一)—— 临界区&自旋锁

  • 基础知识
  • 演示代码
    • 案例一
    • 案例二
  • LOCK
    • 单行代码原子操作
    • 多行代码原子操作
  • 临界区
    • 演示代码
    • 手动实现
  • 自旋锁
    • 分析 KeAcquireSpinLockAtDpcLevel
    • 总结

基础知识

并发:是指多个线程在同时执行

  1. 单核(是分时执行,不是真正的同时)
  2. 多核(在某一个时刻,会同时有多个线程再执行)

同步:则是保证在并发执行的环境中各个线程可以有序的执行

演示代码

注意:如果线程中的代码只对局部变量进行访问,就不存在并发的问题;只有当访问全局变量的时候,才需要关注并发的问题

案例一

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

多核

单核

总结

  1. 自旋锁只对多核有意义
    (查看不同版本的KeAcquireSpinLockAtDpcLevel函数)
  2. 自旋锁临界区、事件、互斥体一样,都是一种同步机制,都可以让当前线程处于等待状态,区别在于自旋锁不用切换线程

Windows事件等待学习笔记(一)—— 临界区自旋锁相关推荐

  1. Windows事件等待学习笔记(二)—— 线程等待与唤醒

    Windows事件等待学习笔记(二)-- 线程等待与唤醒 要点回顾 等待与唤醒机制 可等待对象 可等待对象的差异 线程与等待对象 一个线程等待一个对象 实验 第一步:编译并运行以下代码 第二步:在Wi ...

  2. Windows事件等待学习笔记(四)—— 事件信号量互斥体

    Windows事件等待学习笔记(四)-- 事件&信号量&互斥体 要点回顾 事件 实验:验证SignalState 第一步:编译并运行以下代码 第二步:观察结果 第三步:修改代码并执行 ...

  3. Windows事件等待学习笔记(三)—— WaitForSingleObject函数分析

    Windows事件等待学习笔记(三)-- WaitForSingleObject函数分析 要点回顾 WaitForSingleObject NtWaitForSingleObject KeWaitFo ...

  4. Windows驱动开发学习笔记(七)—— 多核同步内核重载

    Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...

  5. Windows phone 8 学习笔记(5) 图块与通知

    基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认图块,还可以有若干个次要图块.另外,通知与图块的关系比较密切,我们 ...

  6. windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互

    windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互 前面两篇学习笔记分别介绍了IRP和IO_STACK_LOCATION,整个设备栈来处理这个IRP,但是每个设 ...

  7. Windows phone 8 学习笔记(8) 定位地图导航

    Windows phone 8 学习笔记(8) 定位地图导航 原文:Windows phone 8 学习笔记(8) 定位地图导航 Windows phone 8 已经不使用自家的bing地图,新地图控 ...

  8. Windows消息机制学习笔记(三)—— 消息的接收与分发

    Windows消息机制学习笔记(三)-- 消息的接收与分发 要点回顾 消息循环 消息队列 消息的接收 GetMessage 实验1:理解GetMessage 第一步:编译并运行程序A 第二步:编译并运 ...

  9. Windows消息机制学习笔记(一)—— 消息队列

    Windows消息机制学习笔记(一)-- 消息队列 基本概念 实验一:使用代码画出最简单窗口 第一步:编译并运行以下代码 第二步:查看运行结果 第三步:使用其它窗口对其进行覆盖,观察效果 总结 消息队 ...

最新文章

  1. SD-WAN — Overview
  2. (转)linux运行tomcat时JRE_HOME显示不对怎么办?
  3. 数学奥赛用不用计算机,报考自招必看!五大学科竞赛利弊详解,到底哪科最适合你?...
  4. AbstractListView源码分析8
  5. Microsoft AJAX Client Library规范的实例
  6. python内置对象是什么_Python内置对象类型之数字类型
  7. 【Python】Matplotlib绘制三维散点图
  8. java中的原型模式_java中的原型模式理解
  9. python27缺少dll的解决
  10. Java的静态数组和动态数组
  11. java long 转换成 Date
  12. IT6801FN中文版
  13. 区块链游戏:何为虚拟?何为现实?
  14. ECS设置时区与时间
  15. 计算机瞬间关闭所有程序的方法,Win10如何设置关机时快速关闭所有程序
  16. 微信锁屏密码怎么设置
  17. 【学习笔记】H5性能测试
  18. 【NOIP模拟赛】小猫爬山
  19. DraftSight:Linux下完美的AutoCAD
  20. Spark学习总结以及问题

热门文章

  1. CV之FDFA:利用MTCNN的脚本实现对LFW数据集进行FD人脸检测和FA人脸校准
  2. Python语言学习:Python常用自带库(imageio、pickle)简介、使用方法之详细攻略
  3. MAT之SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题
  4. 5.1 Tensorflow:图与模型的加载与存储
  5. Android插件化开发之解决OpenAtlas组件在宿主的注冊问题
  6. css 控制li点与文字的距离
  7. 飘逸的python - 鲜为人知的参数
  8. 国际域名也将列入监管范畴(本文转载自【易名中国】)
  9. TCP传输的单个报文最大字节(MSS和MTU)
  10. 如何用jlink+jflash烧写stm32f103CB的option bytes 和程序