0

与 ReaderWriterLock(或 ReaderWriterLockSlim)一起使用时,有序锁定模式是否可以防止死锁?

显然,该模式可以防止互斥锁死锁。如果我用((N 个带读锁的资源)和(1 个或 2 个带写锁的资源))锁定多个资源,它是否仍然可以防止死锁。

例如:(粗体数字代表具有写锁的资源)

1 2 3 4 5

2 3 4

1 4 5

4

3 回答 3

1

tl; dr 资源排序也可以防止读写锁死锁。

长答案:

画一个这样的等待图:

首先按照规定的顺序从左到右为所有资源绘制一个顶点。

然后,对于每个等待资源的进程,在等待资源的顶点之前绘制一个顶点。如果进程没有等待任何资源,则在所有资源顶点之后在最右侧绘制一个顶点。

然后从每个进程到该进程正在等待的资源绘制一条边,并从每个资源到当前持有该资源的进程绘制一条边。

考虑图上的每条边。有两种情况:

  • 边缘是Pi -> Ri,即从进程到资源。由于每个进程只等待一个资源,并且我们将进程的顶点绘制到它正在等待的资源的左侧,所以边是从左到右的。

  • 边缘是Ri -> Pj,即从资源到进程。如果Pj没有等待任何资源,那么它的顶点在所有资源的右边,因此边是从左到右的。如果Pj 正在等待Rk,则i < k,因为进程按顺序获取资源。如果i < k,则Ri在 的左侧Rk,并且Pj立即在 的左侧Rk(因为我们以这种方式绘制了图形),因此Ri在 的左侧Pj,因此边缘再次从左到右。

由于这样绘制的图的所有边都是从左到右的,那么我们构造了图的拓扑排序,因此图没有环,因此不会发生死锁。

请注意,重要的是进程等待的事实,而不是等待的原因。因此,无论它是否等待互斥锁、读写锁、信号量或其他任何东西——这种防止死锁的策略都适用。

于 2011-11-09T13:37:07.677 回答
0

我认为你做错了有序锁定模式,你必须按顺序抓住所有的锁。要抢“4”的写锁,首先需要抢“3”的写锁。对于“5”,您需要获取“3” “4”“5”的写锁。

使用普通锁,有序锁定模式很昂贵,但使用 SRW 锁,它们非常昂贵,因为您必须先抛出所有读取器。请记住,只有在至少 80% 以上的访问不需要写入锁时,SRW 锁才有优势 - 否则它会非常昂贵,而且您可以使用简单的锁做得更好。

更好的是,尝试将您的代码解耦,这样您就不需要有序锁定(即,我不需要同时访问来自“3”和“4”的数据)。这并不总是可能的,但你的代码越简单,你越能做到这一点。

于 2011-01-20T17:29:04.687 回答
0

我尝试在 C# 中实现有序锁,以检查是否已按固定顺序获取锁。请参阅http://www.codeproject.com/Tips/563154/OrderedLock-in-Csharp

于 2013-03-19T03:34:06.473 回答