- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 ReaderWriterLockSlim
保护一些操作。我想偏爱读者而不是作者,这样当读者长时间持有锁并且作者试图获取写锁时,进一步的读者不会被作者的尝试阻塞(如果作者在 lock.EnterWriteLock()
上被阻止)。
为此,我认为作者可以使用 TryEnterWriteLock
循环中的超时时间很短,这样后续的读者仍然能够获得读锁,而作者却不能。然而,令我惊讶的是,我发现对 TryEnterWriteLock
的调用不成功。更改锁的状态,无论如何都会阻止 future 的读者。概念验证代码:
System.Threading.ReaderWriterLockSlim myLock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.NoRecursion);
System.Threading.Thread t1 = new System.Threading.Thread(() =>
{
Console.WriteLine("T1:{0}: entering read lock...", DateTime.Now);
myLock.EnterReadLock();
Console.WriteLine("T1:{0}: ...entered read lock.", DateTime.Now);
System.Threading.Thread.Sleep(10000);
});
System.Threading.Thread t2 = new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(1000);
while (true)
{
Console.WriteLine("T2:{0}: try-entering write lock...", DateTime.Now);
bool result = myLock.TryEnterWriteLock(TimeSpan.FromMilliseconds(1500));
Console.WriteLine("T2:{0}: ...try-entered write lock, result={1}.", DateTime.Now, result);
if (result)
{
// Got it!
break;
}
System.Threading.Thread.Yield();
}
System.Threading.Thread.Sleep(9000);
});
System.Threading.Thread t3 = new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(2000);
Console.WriteLine("T3:{0}: entering read lock...", DateTime.Now);
myLock.EnterReadLock();
Console.WriteLine("T3:{0}: ...entered read lock!!!!!!!!!!!!!!!!!!!", DateTime.Now);
System.Threading.Thread.Sleep(8000);
});
T1:18-09-2015 16:29:49: entering read lock...
T1:18-09-2015 16:29:49: ...entered read lock.
T2:18-09-2015 16:29:50: try-entering write lock...
T3:18-09-2015 16:29:51: entering read lock...
T2:18-09-2015 16:29:51: ...try-entered write lock, result=False.
T2:18-09-2015 16:29:51: try-entering write lock...
T2:18-09-2015 16:29:53: ...try-entered write lock, result=False.
T2:18-09-2015 16:29:53: try-entering write lock...
T2:18-09-2015 16:29:54: ...try-entered write lock, result=False.
T2:18-09-2015 16:29:54: try-entering write lock...
T2:18-09-2015 16:29:56: ...try-entered write lock, result=False.
T2:18-09-2015 16:29:56: try-entering write lock...
T2:18-09-2015 16:29:57: ...try-entered write lock, result=False.
T2:18-09-2015 16:29:57: try-entering write lock...
T2:18-09-2015 16:29:59: ...try-entered write lock, result=False.
T2:18-09-2015 16:29:59: try-entering write lock...
EnterWriteLock
中。调用,线程 3 被永久阻塞。我可以看到与
ReaderWriterLock
类似的行为.
最佳答案
我忍不住,但我相信这是一个 .NET Framework 错误(更新:我有 reported the bug)。以下简单的程序(上述程序的简化版本)说明了这一点:
var myLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
var t1 = new Thread(() =>
{
Console.WriteLine("T1:{0}: entering read lock...", DateTime.Now);
myLock.EnterReadLock();
Console.WriteLine("T1:{0}: ...entered read lock.", DateTime.Now);
Thread.Sleep(50000);
Console.WriteLine("T1:{0}: exiting", DateTime.Now);
myLock.ExitReadLock();
});
var t2 = new Thread(() =>
{
Thread.Sleep(1000);
Console.WriteLine("T2:{0}: try-entering write lock...", DateTime.Now);
bool result = myLock.TryEnterWriteLock(3000);
Console.WriteLine("T2:{0}: ...try-entered write lock, result={1}.", DateTime.Now, result);
Thread.Sleep(50000);
if (result)
{
myLock.ExitWriteLock();
}
Console.WriteLine("T2:{0}: exiting", DateTime.Now);
});
var t3 = new Thread(() =>
{
Thread.Sleep(2000);
Console.WriteLine("T3:{0}: entering read lock...", DateTime.Now);
myLock.EnterReadLock();
Console.WriteLine("T3:{0}: ...entered read lock!!!!!!!!!!!!!!!!!!!", DateTime.Now);
Thread.Sleep(50000);
myLock.ExitReadLock();
Console.WriteLine("T3:{0}: exiting", DateTime.Now);
});
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
T1
获取读锁。 T2
尝试获取写锁并阻塞,等待超时(因为 T1
持有锁)。 T3
尝试获取读锁并阻塞(因为 T2
被阻塞等待写锁,并且根据文档,这意味着所有进一步的读取器都被阻塞,直到超时)。 T2
的超时时间到期。根据文档,T3
现在应该唤醒并获取读锁。然而,这并没有发生,T3
被永久阻塞(或者,在本例中,在 T1
离开读锁之前的 50 秒内)。 ExitMyLock
在
ReaderWriterLockSlim
’s WaitOnEvent
应该是
ExitAndWakeUpAppropriateWaiters
.
关于.net - 当作者试图进入写锁时如何避免阻塞 ReaderWriterLockSlim 读者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32654687/
有很多关于 ReaderWriterLockSlim 类的文章,它允许多次读取和一次写入。所有这些(至少我发现的)都告诉了如何使用它,而没有太多解释它为什么以及如何工作。标准代码示例是: lock.E
我对 ReaderWriterLockSlim 和延迟 ExitWriteLock 感到沮丧。为什么定时器回调中会释放WriteLock? var _lock = new ReaderWriterLo
我围绕 ReaderWriterLockSlim 编写了一个相当简单的包装器: class SimpleReaderWriterLock { private class Guard : IDi
编辑: 从我已经得到的答案来看,我了解到我提出的第一个解决方案并不是真正的“不阻塞读取”,因为只有一个线程可以进入可升级锁而写锁不能在阅读发布之前采取... 所以我的问题是,如果不存在,如何以正确的方
我正在为在 Windows Azure 中运行的应用程序编写全局错误处理程序/记录器。当应用程序中发生错误时,会执行许多需要自动发生的操作。我需要防止在前一个错误完成之前记录错误。同时,我希望根据需要
我正在编写一个广泛使用多线程的应用程序。一些线程使用 ReaderWriterLockSlim 共享一个 observablecollection。 我有时会遇到死锁,我需要知道在死锁发生时哪个线程持
我有一节课使用 ReaderWriterLockSlim具有一个读取方法和一个写入方法,该方法使用读取方法检索要修改的元素。一个简单的例子是: class FooLocker { Reader
我遇到了这个异常 正在释放读锁而不被持有。 在 System.Threading.ReaderWriterLockSlim.ExitReadLock() 在 .. GetBreed(字符串) 下面是代
我一直在研究集合和线程,并发现了人们创建的漂亮的扩展方法,它们通过允许 IDisposable 模式来简化 ReaderWriterLockSlim 的使用。 但是,我相信我已经意识到实现中的某些东西
我正在使用这段代码在 ReaderWriterLock 上做一个非常愚蠢的基准测试,其中读取的频率是写入的 4 倍: class Program { static void Main()
目前我正在使用 WinDbg 分析转储。 我运行了以下命令(遵循 Tess' incredible walkthrough ): ~* e !clrstack 其中列出了所有线程的所有堆栈。有 300
我正在使用 ReaderWriterLockSlim保护一些操作。我想偏爱读者而不是作者,这样当读者长时间持有锁并且作者试图获取写锁时,进一步的读者不会被作者的尝试阻塞(如果作者在 lock.Ente
Based on Microsoft documentation EnterReadLock 用于在读取模式下锁定。它还表示多个线程可以读取,但一次只能有一个线程写入。 为什么我们应该使用 Enter
我想检查以下代码是否可以抵抗 ThreadAbortException 并且不会导致孤儿锁。如果不是,避免孤儿锁的最佳模式是什么? ReaderWriterLockSlim _lock = new R
我正在使用 ConcurrentBag 在运行时存储对象。在某些时候,我需要清空包并将包中的内容存储到列表中。这就是我所做的: IList list = new List();
我正在调试针对 .NET 3.5 的托管应用程序中的挂起。其中一个线程永远等待方法 System.Threading.ReaderWriterLockSlim.EnterWriteLock。为了找出哪
是否有等效的 Monitor.Pulse 和 Monitor.Wait 可以与 ReaderWriterLockSlim 结合使用? 我有一个类,其中封装了对底层队列的多线程访问。为了对某些东西进行排
我正在尝试实现许多利用 ReaderWriterLockSlim 实现线程安全的属性。所以像大多数人一样,我最终在我的所有属性中都有这样的东西: public string Name { ge
我有一个类 MyClass。此类有一个字段:public ReaderWriterLockSlim rw;(public 用于更简单的示例代码)。许多线程可以使用 rw.EnterReadLock 等
我一直在使用 ReaderWriterLockSlim一段时间以来,它已经满足了我的需求。当我继续微调我的应用程序时,我发现 ReaderWriterLockSlim 对于我的用例来说略显次优。 根据
我是一名优秀的程序员,十分优秀!