【发布时间】:2012-09-12 09:08:49
【问题描述】:
我有一个 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看起来不完全一样,节点多,代码多,但问题如下:
锁定节点后,锁不会被持有,有时。我不明白为什么。 有人解释一下。
*有时意味着我无法知道它何时会发生。
【问题讨论】:
-
很明显,将这段代码复制并粘贴到项目中时,它与您的真实代码不同。其中有许多错误会阻止它编译,如果它们以明显的方式修复,则不会引发异常。请尝试创建一个简短但完整的可编译示例来演示该问题。 (您可能会在尝试这样做时自己发现解决方案)
-
不,这不是真正的代码,现在是代码,但我仍然无法在此处复制整个项目,因为它太长了。这只是对问题的一种解释。
-
您持有的是写锁,而不是读锁。将测试改为 ww.IsWriteLockHeld
-
我说的是WriteLock,只是搞错了。是的,这段代码有效。但在我的整个项目中却没有。
-
同样,如果我们修复了您发布的代码中的编译错误,它不会显示您所描述的问题。我们几乎不可能调试我们没有看到的代码。从一个空项目开始。然后,也许以上述为起点,开始将更多实际代码添加到项目中,直到它真正显示问题。 (然后看看您是否可以删除任何不相关的部分,同时确保它仍然存在问题)
标签: c# .net multithreading synchronization locking