gpt4 book ai didi

c# - EnterWriteLock之后,不保留锁定

转载 作者:行者123 更新时间:2023-12-03 13:20:57 24 4
gpt4 key购买 nike

我有一个AVL树数据结构,其中每个节点都有自己的锁。这是因为有更多的作者试图加入一个节点。

class Node
{
public ReaderWriterLockSlim ww;
// ...
public Node()
{
ww = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
// ...
}
}
class AVL_tree
{
public Node root;
// ...
public void Write(int value)
{
root = new Node();
root.ww.EnterWriteLock();
if (!root.ww.IsWriteLockHeld) throw new Exception("Why?");
// ...
root.ww.ExitWriteLock();
}
}

每个作者都从新线程开始
class Program{
public static AVL_Tree data;
static void Main()
{
data = new AVL_Tree();
List<Thread> vlakna = new List<Thread>();
for (int i = 1; i < 10; i++)
vlakna.Add(new Thread(Write));
foreach (Thread vlakno in vlakna)
vlakno.Start();
}
public static void Write() // Write some random data into the tree
{
Random rnd = new Random(DateTime.Now.Millisecond);
data.Writer(rnd.Next(1, 999));
}

Writer看起来并不完全像这样,有更多的节点和更多的代码,但是问题出在以下地方:

锁定节点后,将不保留锁定, 有时是。我不明白为什么。
有谁的解释。

*有时意味着我无法确定何时会发生。

最佳答案

您确定其他线程正在访问它吗?如果与递归获取锁的线程相同,则将其授予每个递归级别。

若要查看是否发生这种情况,请将锁递归策略更改为NoRecursion,然后查看是否收到异常。

[编辑]

这是另一种想法:您有比赛条件。

您启动的每个线程都在调用data.Write(),即AVL_tree.Write()。

在AVL_tree.Write()内部,您可以分配一个新的根节点。

让我们检查一下您的AVL_tree.Write():

class AVL_tree
{
public Node root;
// ...
public void Write(int value)
{
root = new Node(); // [A]
root.ww.EnterWriteLock(); // [B]
if (!root.ww.IsWriteLockHeld) throw new Exception("Why?"); // [C]
// ...
root.ww.ExitWriteLock();
}
}

想象一下,线程1一直执行到第[B]行,并且关于执行第[C]行。

现在假设线程2出现并执行第[A]行,并且关于执行第[B]行。

此时,根字段已被一个尚未获得其写锁的新字段覆盖。

现在想象线程1继续行[C]。它查看根(现在是由线程2更新的根),并发现未持有写锁,因此引发异常。

我认为这就是正在发生的事情。

关于c# - EnterWriteLock之后,不保留锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12384738/

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