gpt4 book ai didi

c# - ReaderWriterLockSlim LockRecursionPolicy.SupportsRecursion DeadLock

转载 作者:太空宇宙 更新时间:2023-11-03 23:14:31 25 4
gpt4 key购买 nike

我有一个数据库写入操作队列,由一个专用线程管理。我有很多线程可以随时从数据库中读取数据。

我正在使用 ReaderWriterLockSlim 进行读/写访问控制。

我的问题是——为什么不推荐 LockRecursionPolicy.SupportsRecursion? MSDN 文档说:

The use of recursion is not recommended for new development, because it introduces unnecessary complications and makes your code more prone to deadlocks.

这里怎么会死锁呢?例如,如果我在 WriteReadLock 已经获取时尝试调用 EnterReadLock(并且我在 SupportsRecursion 策略下)我得到一个异常......

最佳答案

锁递归是指在同一个线程上多次获取同一个锁而不离开原来的锁。

这样做的主要问题是,首先要进入那种情况,您可能对由谁来处理必要的同步有严重的疑问 - 您的锁可能过于细化或过于全局。多线程很难,让它变得更难是彻头彻尾的傻瓜。

第二个大问题是锁与线程绑定(bind)。但是,如果您正在编写异步代码,您的代码可能会随意地在不同线程之间跳转,这可能意味着看起来要采用递归锁的代码实际上不是——外部锁结束由与内部锁不同的线程拥有,你将永远死锁,线程 A 等待线程 B 完成,而 B 正在等待 A 释放外部锁。

您提到即使启用了递归,ReaderWriterLockSlim 也会抛出大量递归异常。是的,这意味着使用递归锁比使用递归锁更安全一点。 ReaderWriterLockMonitor。 MSDN 中清楚地概述了这些规则:

For a ReaderWriterLockSlim that allows recursion, the following can be said about the modes a thread can enter:

  • A thread in read mode can enter read mode recursively, but cannot enter write mode or upgradeable mode. If it tries to do this, a LockRecursionException is thrown. Entering read mode and then entering write mode or upgradeable mode is a pattern with a strong probability of deadlocks, so it is not allowed. As discussed earlier, upgradeable mode is provided for cases where it is necessary to upgrade a lock.
  • A thread in upgradeable mode can enter write mode and/or read mode, and can enter any of the three modes recursively. However, an attempt to enter write mode blocks if there are other threads in read mode.
  • A thread in write mode can enter read mode and/or upgradeable mode, and can enter any of the three modes recursively.
  • A thread that has not entered the lock can enter any mode. This attempt can block for the same reasons as an attempt to enter a non-recursive lock.

A thread can exit the modes it has entered in any order, as long as it exits each mode exactly as many times as it entered that mode. If a thread tries to exit a mode too many times, or to exit a mode it has not entered, a SynchronizationLockException is thrown.

他们尽最大努力彻底禁止几乎肯定会导致死锁的递归。然而,这并不意味着仍然没有被忽视的死锁(毕竟,您不需要递归来导致死锁——它只是给您很多难以找到的死锁机会)。更不用说在定期递归其锁的代码中很难做任何一致性保证——这可能意味着某些操作在从外部锁调用时是(半)原子的,但在直接调用它们时不再是原子的。

多线程已经够难了。不要仅仅因为你的对象设计被破坏就让它变得更难 :) Joe Albahari 的“C# 中的线程”是对多线程的一个很好的介绍(一般来说,特别是在 .NET 中),可以在互联网上免费获得(谢谢,乔!)。 ReaderWriterLockSlim 特别在 http://www.albahari.com/threading/part4.aspx#_Reader_Writer_Locks 中处理

关于c# - ReaderWriterLockSlim LockRecursionPolicy.SupportsRecursion DeadLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37720533/

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