.NET SpinLock 未释放 Thread.BeginCriticalSection

发布于 2024-10-30 09:30:07 字数 1172 浏览 5 评论 0原文

使用.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.EndCriticalRegion,而没有调用 Thread.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 的调用是否会产生任何问题?

Using .NET reflector, I find that the SpinLock structure has a lot of cases where it calls Thread.BeginCriticalRegion and doesn't call Thread.EndCriticalRegion.
For example, in the public function 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();
// ...

In another case, SpinLock.Exit seems to call Thread.EndCriticalRegion without having called Thread.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();   // <--- ??
}

So the question: do any problems ensue from not balancing calls to Begin/EndCriticalRegion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

留蓝 2024-11-06 09:30:07

请注意,如果实际获取了锁,然后通过调用 Exit() 释放锁,则 Begin/End 会调用 do 平衡。标记关键区域的调用对于让 CLR 知道在获取 SpinLock 时线程中断可能会造成破坏是必要的。有关详细信息,请参阅此处

Note that the Begin/End calls do balance if the lock is actually taken and then released by calling Exit(). The calls to mark the critical region are necessary to let the CLR know that thread interruptions may be damaging while a SpinLock is acquired. See here for more info.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文