在<<Windows网络与通信程序设计>>有一段话讲spin lock:在相同处理器上,运行在更高IRQL的线程虽然可以强占执行的线程,但是这些现成并不能获取旋转锁,因为旋转锁的IRQL比他们的还低.请大牛解释下这段话吧,为什么旋转锁的IRQL比他们的还低,其他更高IRQL的线程反而不能获取旋转锁?

解决方案 »

  1.   

    自旋锁是这么搞的。首先运行在PASSIVE_LEVEL 的线程通过KeAcquireSpinLock  从而调用KfAcquireSpinLock获得自旋锁,而KeAcquireSpinLock会提高你的IRQL到DISPATCH_LEVEL,如果当前IRQL就是DISPATCH_LEVEL,那么就调用KeAcquireSpinLockAtDpcLevel,省去提升IRQL一步。看DDK
    #if defined(_X86_)#define KeAcquireSpinLock(a,b)  *(b) = KfAcquireSpinLock(a)
    #define KeReleaseSpinLock(a,b)  KfReleaseSpinLock(a,b)#else//
    // These functions are imported for IA64, ntddk, ntifs, nthal, ntosp, and wdm.
    // They can be inlined for the system on AMD64.
    //#define KeAcquireSpinLock(SpinLock, OldIrql) \
        *(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock)你的,明白?KfAcquireSpinLock,KeAcquireSpinLockAtDpcLevel除了不提升IRQL到DISPATCH_LEVEL,其他是一样的效果。都能得到锁MSDN上有这样一段文字:
    当IRQL= DISPATCH_LEVEL时,驱动调用KeAcquireSpinLockAtDpcLevel比调用KeAcquireSpinLock 有更好的性能。当IRQL<DISPATCH_LEVEL时,驱动必须调用KeAcquireSpinLock。
      

  2.   

    其实书上说的并不完全对,不是不能得到,从效率的角度上说不完全对,因为从逆向的角度来说,KeAcquireSpinLockAtDpcLevel比KeAcquireSpinLock少了2个Mov指令
      

  3.   


    谢谢大牛对自旋锁清晰的描述.那本书上好象在暗示 "自旋锁自身也有对应的IRQL"?把我搞晕头了...不是只有线程才会有IRQL么?况且线程得到自旋锁后自身的IRQL提升到DISPATCH_LEVEL后肯定不会被其他的线程切换.难道是拥有自旋锁线程的IRQL变了则它拥有的自旋锁的IRQL反而是最低的的吗?
      

  4.   

    自旋锁自身也有对应的IRQL,这句话牛头不对马嘴。
      

  5.   

    它的原话:
    旋转锁的获取使得线城的IRQL临时的提升到了与旋转锁相关的级别.这阻止了相同的处理器上所有更低IRQL的线程强占执行的线程.在相同处理器上,运行在更高的线程虽然可以强占执行的线程,但是这些现成并不能获取旋转锁,因为旋转锁的IRQL比它们的还低.因此,一旦线程获取了旋转锁,直到释放它为止,不会再有其他现成获取此旋转锁了.好的驱动应该尽量减少拥有旋转锁的时间.它里面用了两次"在相同的处理器",但意思却矛盾...
      

  6.   

    旋转锁相关的级别,也许就是指的DISPATCH_LEVEL吧,它说 “相关”,没说“相同”
      

  7.   

    下面有句话:"因为旋转锁的IRQL比它们的还低"我没有抄错.
      

  8.   

    如果是我自己理解错误的话,我想知道"在相同处理器上,运行在更高IRQL的线程虽然可以强占执行的线程,但是这些现成并不能获取旋转锁,因为旋转锁的IRQL比他们的还低."这句话到底想表达什么样的意思?有没有代码描述的 
      

  9.   

    你没理解我的意思。“...因为旋转锁的IRQL”这句话的意思想表达的应该是这样,获得自旋锁之后的线程的IRQL,它可能是被编辑改得不好了,所以让你误解了。
    自旋锁本身是没有IRQL这一说的,就像你拿到了一个令牌后,你可以号令武林了,但是单令牌自己是不能号令武林的,不知道你明白我想说的没