.NET SpinLock没有释放Thread.BeginCriticalSection

时间:2011-04-05 03:15:46

标签: .net spinlock

使用.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的调用会产生任何问题吗?

1 个答案:

答案 0 :(得分:1)

请注意,如果实际执行锁定,则开始/结束调用执行平衡,然后通过调用Exit()释放。标记关键区域的调用对于让CLR知道在获取SpinLock时线程中断可能是有害的是必要的。有关详细信息,请参阅here