分类: LINUX
2010-07-28 10:13:07
以下部分的来源:
自旋锁我的理解就好比 小A,小B,小C,小D 同住一个屋子,可屋子只有一间茅房和一个马桶。他们谁想"便"的时候谁就要把茅房的门锁上,然后占据马桶,比如小A正在占有,聚精会神,非常惬意。碰巧小 C此时甚急,但没办法,因为小A已经把门上了锁。于是小B在门口急得打转,即为"自旋"。注意这个"自旋"两个字用的好,小B不是一看门被上锁就回屋睡觉 去了,而是在门口"自旋"。... 最终的结果是小A开锁,小B占用。而且在开锁闭锁过程中动作干净利落,不容他人抢在前面。 如此周而复始...... 这里的 小A,B,C,D 即为处理器,茅房的锁即为自旋锁。当其他处理器想访问这个公共的资源的时候就要先获取这个锁。如果锁被占用,则自旋(循环)等待。 小A的聚精会神代表了IRQL为2,开关锁动作快表示为原子操作。 ---------------------------------------------------------- 不知道我理解的对还是不对,可能这样举例有些不恰当。有理解不对之处希望指点一二,以免误入歧途,悔之晚矣。 ---------------------------------------------------------- 写了个测试程序测试了一下: KSPIN_LOCK spinlock; NTSTATUS DriverEntry( DeviceObject = NULL; RtlInitUnicodeString( &DeviceName, deviceNameBuffer ); DriverObject->DriverUnload = DriverUnload; KeInitializeSpinLock( &spinlock ); // (2) PsCreateSystemThread( &ThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadRoutine, NULL ); i = 10000; KeAcquireSpinLock( &spinlock, &oldirql ); while (i--) KeReleaseSpinLock( &spinlock, oldirql ); return Status; VOID i = 10000; KeAcquireSpinLock( &spinlock, &oldirql ); // (1) while (i--) KdPrint(( "**[%d] CurrentIrql:\t%d", Processor, irql )); KeReleaseSpinLock( &spinlock, oldirql ); // (1) --------------------------------------------------------------------------------- 首先说明一下我是双核系统,如果是单核的话我想进入自旋锁之后IRQL已经提高到 DPC 级别,第二个线程就跑不起来了。如果他神奇的跑了起来,那一定会发生死锁。 分几种情况测试: 1、就是上边的代码测试 先抓到锁的先跑,后抓到锁的后跑。并且被锁的期间的IRQL 为 DPC 级别。 2、去掉 标记 (1) 的两行 结果是两个线程同时跑,一个占处理器 [0] 一个占处理器 [1] 上锁的那个 IRQL 级别是 DPC 级。 没上锁的IRQL为 0 即 自旋锁 并不影响其他处理器的正常运行。除非其他处理器也想获得这个锁。 3、去掉 标记 (2) 的一行(spinlock 是全局变量) 和 1 的结果相同,因为全局变量默认是初始化为0的。 |