内核中的同步机制(一)

来源:互联网 发布:matlab编程 郑碧波 译 编辑:程序博客网 时间:2024/05/16 08:25

数据的同步

★.提升IRQL实现同步

单核CPU上只要提升到DISPATCH_LEVEL就能实现数据的同步,因为线程不会切换。在多核CPU环境下,也有利用IRQL的提升来处理处理器相关的数据同步的必要。一个例子是线程调度时的同步处理,参考前面的文章~

★.利用cpu的原子操作执行,x86下的lock前缀对数据进行同步访问。例如lock xadd,xchg,lock cmpxchg,lock or lock xor lock and等等

单链表的同步也是使用64位的原子操作实现的, 

typedef union _SLIST_HEADER {    ULONGLONG Alignment;    struct {        SLIST_ENTRY Next;        WORD   Depth;        WORD   Sequence;    } DUMMYSTRUCTNAME;} SLIST_HEADER, *PSLIST_HEADER;


Alignment就是原子操作要同步的数据,lock excmpchg8b 来尝试同步这个64位整数,不能获取就继续尝试,从而实现一个后进先出的同步单链表操作

★.自旋锁

内核态自旋锁,结构定义typedef ULONG_PTR KSPIN_LOCK;

实际就是一个状态,程序将锁包含造一个结构里面,每次访问这个结构时获取这个锁来达到同步

自旋锁的原理是将irql提升到DISPATCH_LEVEL,然后不断获取锁得状态,直到能够成功获取为止,单核下显然没啥意义,因为升到DISPATCH_LEVEL意味着线程不能调度…so…DeadLock….所以单核下获取锁只是简单的提升irql


自旋锁要求所有访问这个资源的代码都要事先获取这个锁,否则一个线程获取了这个锁,另一个线程却直接访问数据。。%¥&……¥

下面看一下 初始化 获取、释放锁的几个过程

KeInitializeSpinLock 简单的给锁赋值为0

#define KeAcquireSpinLock(a,b) *(b) = KfAcquireSpinLock(a)
#define KeReleaseSpinLock(a,b) KfReleaseSpinLock(a,b)

X86下 获取自旋锁的操作函数是在HAL中完成的,因为有单核多核之分,用的是不同的hal,一下调试信息来源于一篇文章,我的符号不知道怎么死活下载不下来了。。。。

hal!KfAcquireSpinLock:    mov     edx,dword ptr ds:[0FFFE0080h]    mov dword ptr ds:[0FFFE0080h],41h    shr     edx,4    movzx   eax,byte ptr hal!HalpVectorToIRQL [edx]    ret


就是提升IRQL到DPC_LEVEL ,只要线程不切换,自然没有人跟我抢这个数据

多核下

hal!KfAcquireSpinLock:    mov     eax,dword ptr fs:[00000024h] ;得到当前的IRQL    mov     byte ptr fs:[24h],2           ; 提升到DISPATCH_LEVEL    jmp     hal!KeAcquireSpinLockRaiseToSynch+0xe hal!KeAcquireSpinLockRaiseToSynch:    mov     eax,dword ptr fs:[00000024h]    mov     byte ptr fs:[24h],1Bhhal!KeAcquireSpinLockRaiseToSynch+0xe   lock bts dword ptr [ecx],0 ;原子方式进行比对锁的最后一位,若是原来0置1返回   jb      hal!KeAcquireSpinLockRaiseToSynch+0x16 若原来是1,则跳转   rethal!KeAcquireSpinLockRaiseToSynch+0x16   test    dword ptr [ecx],1    比对是否是1   je      hal!KeAcquireSpinLockRaiseToSynch+0xe 不是1了跳转到0xe   pause    否则休息一下   jmp     hal!KeAcquireSpinLockRaiseToSynch+0x16 ;继续比对

说白了就是一个循环比对的操作,由于比较浪费资源(一直在打转,从未被切换),所以自旋锁只适合短时间内的同步 不宜长久等待

也有一些针对自旋锁优化的函数 
排队自旋锁,利用KPCR的LockQueue对锁进行排队,仅供系统内部使用
栈内自旋锁KeAcquireInStackQueuedSpinLock

原理都是一样的,详情可参考文末的参考链接

By ReturnsMe http://hi.baidu.com/andriy_aolala/blog/item/c4639b3ed12467ea828b13b9.html

参考文章

        明明白白自旋锁

        Windows 自旋锁分析

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 合租房没有阳台晒衣服怎么办 车门锁了钥匙在里面怎么办 邻居忘带钥匙你看见会怎么办 把车钥匙锁车里了怎么办 偷了东西不承认怎么办 孩子偷了东西不承认怎么办 公司员工偷了东西不承认怎么办 知道被谁偷了没有证据怎么办 被贼偷了知道是谁没有证据怎么办 前任要去部队闹怎么办 站久了腿粗怎么办 机械表表带长了怎么办 恶魔之眼褪色了怎么办 恶魔之眼掉色后怎么办 练瑜伽出汗瑜伽垫手滑怎么办 cf多出来的神器怎么办 脖子痛得低不了怎么办 六岁的孩孑不吃.饭怎么办 大腿肌肉练废了怎么办 吃鸡里的信誉分太低怎么办she 血压高老是晕怎么办27 我腰疼的厉害怎么办 奥克斯空调外机上霜风扇不转怎么办 燃脂膏辣辣的怎么办 减肥期间暴食了怎么办 健身减脂后腹部皮松怎么办 吃减肥药上火怎么办呢 魔域怀旧版新区进不去怎么办 dnf十周年礼盒打开了怎么办 房地产项目完成后企业员工怎么办啊 韩服lol延迟太高怎么办 LOL等级奖励卡掉怎么办 魔域手机号换了怎么办 买的qq号找回了怎么办 买dnf账号被找回怎么办 微博账号已锁定怎么办 抖音账号封手机怎么办 手机号码绑定被别人占用了怎么办 DNF账号给找回了怎么办 转转上被骗了200怎么办 7彩账号被锁定怎么办