阅读:2074回复:15
为何自旋锁未能起作用?
我在AddDevice里初始化了一个SPINLOCK然后在DispatchIOCtl例程的某两个(设为A,B)IoCtl的处理代码段中用KeAcquireSpinLock和KeReleaseSpinLock各锁住一段代码,结果发现先到来的A获得锁但未释放时,后到来的B竟也能获得锁进入了关键代码段.我以前从为见过这种现象,想不通为什么?或者是我疏忽了什么?请各位提点建议.在下不胜感激.
|
|
最新喜欢:![]() |
沙发#
发布于:2002-05-27 10:35
关于自旋锁,我写了一段代码: 你不妨在你的dispatch routine中这样试试,Acquire之后不release... 保证会死锁. |
|
|
板凳#
发布于:2002-05-27 10:32
关于自旋锁,我写了一段代码: 对于uniprocessor,这段代码不会死锁,对多处理器系统那是100%死锁。因为实现机理不一样。 SpinLock一般用于多个任务之间的互锁,你这样用实际违背了其原意。 |
|
|
地板#
发布于:2002-05-27 08:53
关于自旋锁,我写了一段代码:
在资源初始化结束后, KIRQL OldIrql0,OldIrql1; KeInitializeSpinLock(&dx->SpinLock); //1 KeAcquireSpinLock(&dx->SpinLock,&OldIrql0); KeAcquireSpinLock(&dx->SpinLock,&OldIrql1); KeReleaseSpinLock(&dx->SpinLock,OldIrql1); KeReleaseSpinLock(&dx->SpinLock,OldIrql0); //2 DebugPrint(\"ok!\"); 这段代码应当会死锁,但实际运行中没有死锁, 为了测试在不同的irql上运行,我在1处 加了升高irql到DISPATCH_LEVEL的代码, 在2处将IRQL降到PASSIVE_LEVEL 还是没有死锁。 有没有人可以解释一些 |
|
地下室#
发布于:2002-05-26 21:02
SPINLOOK永远都是在DIRQL工作的!!不会高也不会低!!从PASSIVE和DISPATCH都可以调用!只要是在内核层内!而且不低于DIRQL都可以调用!!!其实SPINLOCK的原理很简单!就是把某段代码放到DIRQL运行,并为它维护一个句柄!这个句柄同时只能有一个线程可以获得,获得这个句柄就好象门票一样!不过是出来的时候要还给IO管理器罢了! SPINLOOK有很多种类的,普通spinlock的将提升IRQL至Dispatch Level 参见http://sys.xiloo.com/documents/irql.htm |
|
|
5楼#
发布于:2002-05-25 21:58
form walt oney:
自旋锁 -------------------------------------------------------------------------------- IRQL概念仅能解决单CPU上的同步问题,在多处理器平台上,它不能保证你的代码不被运行在其它处理器上的代码所干扰。一个称为自旋锁(spin lock)的原始对象可以解决这个问题。为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子操作,该操作测试并设置(test-and-set)某个内存变量,由于它是原子操作,所以在该操作完成之前其它CPU不可能访问这个内存变量。如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行。如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个“测试并设置(test-and-set)”操作,即开始“自旋”。最后,锁的所有者通过重置该变量释放这个自旋锁,于是,某个等待的test-and-set操作向其调用者报告锁已释放。 关于自旋锁有两个明显的事实。第一,如果一个已经拥有某个自旋锁的CPU想第二次获得这个自旋锁,则该CPU将死锁(deadlock)。自旋锁没有与其关联的“使用计数器”或“所有者标识”;锁或者被占用或者空闲。如果你在锁被占用时获取它,你将等待到该锁被释放。如果碰巧你的CPU已经拥有了该锁,那么用于释放锁的代码将得不到运行,因为你使CPU永远处于“测试并设置”某个内存变量的自旋状态。 关于自旋锁的另一个事实是,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。所以,为了避免影响性能,你应该在拥有自旋锁时做尽量少的操作,因为此时某个CPU可能正在等待这个自旋锁。 关于自旋锁还存在着一个不太明显但很重要的事实:你仅能在低于或等于DISPATCH_LEVEL级上请求自旋锁,在你拥有自旋锁期间,内核将把你的代码提升到DISPATCH_LEVEL级上运行。在内部,内核能在高于DISPATCH_LEVEL的级上获取自旋锁,但你和我都做不到这一点。 |
|
6楼#
发布于:2002-05-25 21:45
SPINLOOK永远都是在DIRQL工作的!!不会高也不会低!!从PASSIVE和DISPATCH都可以调用!只要是在内核层内!而且不低于DIRQL都可以调用!!!其实SPINLOCK的原理很简单!就是把某段代码放到DIRQL运行,并为它维护一个句柄!这个句柄同时只能有一个线程可以获得,获得这个句柄就好象门票一样!不过是出来的时候要还给IO管理器罢了!
|
|
|
7楼#
发布于:2002-05-25 21:32
spinlock will not work in dispatch level or higher.
in dispatch level or higher, program need not dealing this, beucase no thread context switch :D :D :D we use spinlock only when we need , not because we want to use it. |
|
8楼#
发布于:2002-05-25 19:47
不会吧?DDK里面好多用自镟锁的,怎么会不灵?
|
|
9楼#
发布于:2002-05-25 17:15
我以前也想用自旋锁做互斥,后来发现根本不灵,锁住后一样可以 WHO说的WHO说的??如果真的是不灵的话,就不存在资源保护了!你做过没有啊??不要随便听谣言!MS的东西MS说的还是比较权威的!我估计是他的代码的问题而不是SPINLOCK的问题~ |
|
|
10楼#
发布于:2002-05-25 16:53
我以前也想用自旋锁做互斥,后来发现根本不灵,锁住后一样可以
进去,后来我就改用别的方式了, 我和linux下写驱动的人讨论过这个问题,他们说linux下的自旋锁 也有同样的现象,ddk文档写自旋锁就是在多CPU之间做互斥的 |
|
11楼#
发布于:2002-05-24 17:59
是不是啊??你用VERIFIER来看看获得了几次SPINLOCK的时候出现这个问题的??单数还是双数??
|
|
|
12楼#
发布于:2002-05-24 17:32
自旋锁是针对多CPU而言的,对单CPU并没有任何的作用 对uniprocessor及multi-processor,SpinLock的实现机制不一样,但其结果是一样的,即实现互斥。 不妨把程序段贴出来。如果你的实现与你所说的一致,也不会出现此类问题。 |
|
|
13楼#
发布于:2002-05-24 16:38
自旋锁是用于互斥资源的访问的,好象与CPU个数无关喔??
|
|
|
14楼#
发布于:2002-05-24 15:12
自旋锁是针对多CPU而言的,对单CPU并没有任何的作用
|
|
15楼#
发布于:2002-05-24 15:04
锁初始化错误?导致这两个函数失败吧。检查一下输入参数和返回值,看看是什么错误码。
|
|