我有一个数据库写入的行动队列,由一个专门的线程管理。我有很多线程可以随时从数据库读取。
我使用ReaderWriterLockSlim进行读写访问控制。
我的问题是-为什么不推荐LockRecursionPolicy.SupportsRecursion?MSDN文档说:
不建议在新开发中使用递归,因为它会带来不必要的复杂性,并使您的代码更容易陷入死锁。
如何才能在这里实现僵局?例如,如果我尝试调用EnterReadLock时,WriteReadLock已经获得(而且我在SupportsRecursion策略下),我会得到一个异常.
发布于 2016-06-09 08:54:37
锁递归是指在同一个线程上多次使用相同的锁,而不保留原来的锁。
这方面的主要问题是,首先要处理这种情况,您可能会遇到严重的问题,需要由谁来处理所需的同步--您的锁可能太细,或者太全局。多线程是困难的,使它更加困难是完全愚蠢的。
第二个大问题是锁被绑在线程上。但是,如果您正在编写异步代码,您的代码可能会随意地在不同的线程之间跳跃--这可能意味着似乎正在接受递归锁的代码没有--外部锁最终被一个不同于内部锁的线程所拥有,并且您永远与线程A陷入僵局,等待线程B完成,而B正在等待A释放外部锁。
您提到过,即使启用了递归,ReaderWriterLockSlim也会抛出许多递归异常。是的,这意味着使用递归锁比处理例如ReaderWriterLock或Monitor时稍微安全一些。这些规则在MSDN中有明确的概述:
对于允许递归的ReaderWriterLockSlim,可以对线程可以进入的模式进行如下说明:
一个线程可以以任何顺序退出它所输入的模式,只要它退出每种模式的次数与它进入该模式的次数相同。如果一个线程试图退出模式太多次,或者退出它尚未进入的模式,则会引发SynchronizationLockException。
他们尽了最大的努力完全不允许递归,这几乎保证会导致死锁。然而,这并不意味着仍然没有不被注意到的死锁(毕竟,您不需要递归来导致死锁--它只是给您提供了大量寻找死锁的机会)。更不用说在代码中经常递归其锁的任何一致性保证都是相当困难的--这可能意味着某些操作在从外部锁调用时是(半)原子的,但当它们被直接调用时就停止了。
多线程已经足够困难了。不要仅仅因为你的对象设计被破坏了就让它变得更加困难:)对多线程的一个很好的介绍(通常,特别是在.NET中)是Joe的“C#中的线程”,免费提供(谢谢,Joe!)。尤其是ReaderWriterLockSlim是在Locks中处理的
https://stackoverflow.com/questions/37720533
复制相似问题