gpt4 book ai didi

c# - ReaderWriterLockSlim 的神秘死锁损坏

转载 作者:行者123 更新时间:2023-11-30 18:12:23 25 4
gpt4 key购买 nike

我围绕 ReaderWriterLockSlim 编写了一个相当简单的包装器:

class SimpleReaderWriterLock
{
private class Guard : IDisposable
{
public Guard(Action action)
{
_Action = action;
}

public void Dispose()
{
_Action?.Invoke();
_Action = null;
}

private Action _Action;
}

private readonly ReaderWriterLockSlim _Lock
= new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

public IDisposable ReadLocked()
{
_Lock.EnterReadLock();
return new Guard(_Lock.ExitReadLock);
}

public IDisposable WriteLocked()
{
_Lock.EnterWriteLock();
return new Guard(_Lock.ExitWriteLock);
}

public IDisposable UpgradableReadLocked()
{
_Lock.EnterUpgradeableReadLock();
return new Guard(_Lock.ExitUpgradeableReadLock);
}
}

(这可能不是世界上最高效的事情,所以我也对此类的改进建议感兴趣。)

它是这样使用的:

using (_Lock.ReadLocked())
{
// protected code
}

(有大量的读取非常频繁地发生,几乎没有任何写入。)

这似乎总是在 Release模式和生产中按预期工作。然而,在 Debug模式和调试器中,进程偶尔会在一种特殊状态下死锁——它调用了 EnterReadLock,锁本身没有被任何东西持有(所有者为 0,报告的属性是否有任何读者/作者/服务员拒绝等等)但是里面的自旋锁是锁着的,它在那里不停地旋转。

我不知道是什么触发了这个,除了如果我在断点处停止并单步执行(在完全不相关的代码中),它似乎更频繁地发生。

如果我手动将自旋锁 _isLocked 字段切换回 0,则该过程将恢复,之后一切似乎都按预期工作。

代码或锁本身有问题吗?调试器是否在做一些意外引发自旋锁死锁的事情? (我使用的是 .NET 4.6.2。)

我读过 an article这表明 ThreadAbortException 可能是这些锁的问题——我的代码确实在某些地方调用了 Abort()——但我没有 认为 那些涉及调用此锁定代码的代码(尽管我可能会弄错),如果问题是锁已被获取但从未释放,那么它应该看起来与我所看到的不同。 (尽管顺便说一句,框架文档特别禁止在受限区域获取锁,正如那篇文章所鼓励的那样。)

可以更改代码以避免锁定间接,但是使用 守卫通常不是推荐的做法吗?

最佳答案

由于 using 语句 is not abort-safe ,您可以尝试将其替换为 linked article 中建议的中止安全解决方法.像这样:

public void WithReadLock(Action action)
{
var lockAcquired = false;
try
{
try { }
finally
{
_Lock.EnterReadLock();
lockAcquired = true;
}
action();
}
finally
{
if (lockAcquired) _Lock.ExitReadLock();
}
}

用法:

var locker = new SimpleReaderWriterLock();
locker.WithReadLock(() =>
{
// protected code
});

关于c# - ReaderWriterLockSlim 的神秘死锁损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55467344/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com