2011-04-05 59 views
1

使用.NET反射,我發現自旋鎖結構有很多情況下,它調用Thread.BeginCriticalRegion,並且不調用Thread.EndCriticalRegion。 例如,在公共職能SpinLock.Enter(REF布爾lockTaken)(.NET 4.0):.NET自旋鎖不釋放Thread.BeginCriticalSection

// ... 
Thread.BeginCriticalRegion(); 
if (Interlocked.CompareExchange(ref this.m_owner, managedThreadId, owner, ref lockTaken) == owner) 
    return; // <--- !! 
Thread.EndCriticalRegion(); 
// ... 

在另一種情況下,SpinLock.Exit好像叫Thread.EndCriticalRegion,而不必叫主題。 BeginCriticalRegion

public void Exit(bool useMemoryBarrier) 
{ 
    if (this.IsThreadOwnerTrackingEnabled && !this.IsHeldByCurrentThread) 
     throw ... 

    if (useMemoryBarrier) 
    { 
     if (this.IsThreadOwnerTrackingEnabled) 
      Interlocked.Exchange(ref this.m_owner, 0); 
     else 
      Interlocked.Decrement(ref this.m_owner); 
    } 
    else if (this.IsThreadOwnerTrackingEnabled) 
     this.m_owner = 0; 
    else 
    { 
     int owner = this.m_owner; 
     this.m_owner = owner - 1; 
    } 
    Thread.EndCriticalRegion(); // <--- ?? 
} 

所以問題:由於沒有平衡對Begin/EndCriticalRegion調用的任何問題?

回答

1

請注意,開始/結束調用平衡如果鎖實際上被採取,然後通過調用Exit()釋放。標記關鍵區域的調用對於讓CLR知道在獲取SpinLock時線程中斷可能會造成損害是必要的。有關更多信息,請參見here

+0

感謝您的信息;我沒有想到這一點,因爲我本能地認爲CriticalRegion不應該被置於不可預測的外部代碼之上。 – 2011-04-05 03:39:23