1

すべてのノードが独自のロックを持つ 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));
    }

ライターはこのようには見えません。より多くのノードとより多くのコードがありますが、問題は次のとおりです。

ノードをロックした後、ロックが保持されないことがあります。理由がわかりません。誰か何らかの説明をしてください。

※いつになるか分からない場合もございます。

4

1 に答える 1

3

別のスレッドからアクセスされていますか? 同じスレッドが再帰的にロックを取得している場合、すべての再帰レベルに付与されます。

これに該当するかどうかを確認するには、ロックの再帰ポリシーを 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 によって新しく作成されたルート) を確認し、書き込みロックが保持されていないことを発見し、例外をスローします。

それが起こっていると思います。

于 2012-09-12T09:20:47.910 に答える