使用 .NET 反射器,我发现SpinLock结构在很多情况下调用Thread.BeginCriticalRegion而不调用Thread.EndCriticalRegion。例如,在公共函数 SpinLock.Enter(ref bool lockTaken) (.NET 4.0) 中:
// ...
Thread.BeginCriticalRegion();
if (Interlocked.CompareExchange(ref this.m_owner, managedThreadId, owner, ref lockTaken) == owner)
return; // <--- !!
Thread.EndCriticalRegion();
// ...
在另一种情况下, SpinLock.Exit 似乎在没有调用Thread.BeginCriticalRegion的情况下调用了 Thread.EndCriticalRegion。
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 的调用是否会出现任何问题?