gpt4 book ai didi

c# ReaderWriterLockSlim 在调用 ExitReadLock 的中断线程后损坏

转载 作者:太空宇宙 更新时间:2023-11-03 11:07:10 24 4
gpt4 key购买 nike

我遇到过 ReaderWriterLockSlim 似乎在一系列法律行动后被破坏的场景。

流程是:

  1. 线程 1 获取 writer lock1
  2. 线程 2 尝试获取读者锁 1 - block
  3. 线程 2 被中断,并调用 lock1.ExitReadLock线程 2 没有获得锁。看来应该抛出异常了。
  4. 线程 1 退出 lock1 的写锁
  5. 任何试图获取 lock1.EnterReadLock 的线程都将永远阻塞

在上面的第 3 阶段之后,调试器显示 lock1.CurrentReadCount 已损坏 - 似乎已溢出到 0x7FFFFFF。

我想知道是否有人遇到过这种情况,或者我可能遗漏了什么。

重现它的代码:

[TestMethod]
public void ReproTest()
{
var rwlock = new ReaderWriterLockSlim();
rwlock.EnterWriteLock();

bool taken = false;
var reader = new Thread(() =>
{
try
{
rwlock.EnterReadLock();
s_logger.Info("Enter");

}
catch (ThreadInterruptedException)
{
rwlock.ExitReadLock();
}
});
reader.Name = "Reader";
reader.Start();
Thread.Sleep(1000);

reader.Interrupt();

Thread.Sleep(1000);

rwlock.ExitWriteLock();

while (!taken)
{
taken = rwlock.TryEnterReadLock(1000);
}

Thread.Sleep(1000);
}

最佳答案

这看起来像是框架中的一个错误(在 v3.5 和 v4.0 上测试过)。 ExitReadLock() 应该抛出一个 SynchronizationLockException,但在这种情况下不会。事实上,您可以通过以下更简单地触发一个非常相似的问题:

rwlock.EnterReadLock();
rwlock.ExitReadLock();
// This should throw a SynchronizationLockException but doesn't
rwlock.ExitReadLock();
// At this point, rwlock.CurrentReaderCount = 0x0fffffff

(事实上,如果在之前进入锁的任何线程上调用时没有匹配的 EnterReadLock() 调用它,ExitReadLock() 将损坏锁。)

仅当使用无参数构造函数或使用 LockRecursionPolicy.NoRecursion 创建 ReaderWriterLockSlim 时才会出现此问题。如果使用 LockRecursionPolicy.SupportsRecursion 创建,它不会被不匹配的 ExitReadLock() 破坏。

如果您希望读取器线程在等待进入锁时被中断,我建议将读取器线程方法更改为:

var reader = new Thread(() =>
{
var entered = false;
try
{
rwlock.EnterReadLock();
entered = true;
s_logger.Info("Enter");
}
finally
{
if (entered) rwlock.ExitReadLock();
}
});

关于c# ReaderWriterLockSlim 在调用 ExitReadLock 的中断线程后损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15461315/

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