2016-10-28 8 views
0

私のコードはAVLツリーで、mutexで入力しようとしています。ミューテックスは機能しません

mutexは機能しません。どうして?

黒い画面を返します。おそらくデッドロックです。 私は分かりません。 再帰関数はありません。

lock guardを使用すると正常に動作します。 std::lock_guard

template<typename T> int avl<T>::insere (int key , T data) { 

    mtx.lock(); 

    no * nw = new no; 

    if (nw == NULL) 
     return 0; 

    nw->sire = NULL; 
    nw->left = NULL; 
    nw->right = NULL; 
    nw->key = key; 
    nw->data = data; 

     if (tree.root == NULL) { 
     tree.root = nw; 
     tree.quant++; 
     return 1; 
    } 
    no * son = tree.raiz; 
    no * sire = NULL; 

    while (son != NULL) { 

     sire = son; 

     if (key < son->key) 
      son = son->left; 

     else 
      son = son->right.; 

    } 
    nw->sire = sire; 

    if (key < sire->key) 
     sire->left = nw; 

    else 
     sire->right = nw; 

    tree.quantidade++; 

    no * current = nw; 

    while (current != NULL) { 

     int f = fator (nw); 

     if (f >= 2 || f <= 2) 
      balance(current); 
     current = current->sire; 
    } 

    mtx.unlock(); 

    return 1; 
} 
+3

あなたのミューテックスをロック解除しない関数には複数のreturn文があります。 lock_guardはこれを自動的に行います。あなたがそれを使用しない場合は、返す前にミューテックスをロック解除する必要があります – Hayt

+0

ありがとう、それは働いた –

答えて

3

RAIIと呼ばれる概念(リソース獲得は初期化され)、短い中

RAIIを使用しています:あなたは、コンストラクタでアクションを行うと、デストラクタで「元に戻す」操作を行います。ミューテックスの場合、これはunlock

ですので、return(範囲外になる)になると、lock_guardとなると、mutexは自動的にロック解除されます。

「手動」ミューテックスに変更するときは、機能の可能な出口(それぞれreturnの前)にunlockを必ず実行する必要があります。

これがRAIIクラスが存在する理由です。だから、これについて心配する必要はありません。機能を変更して別のreturnを追加すると、unlockを追加することを忘れることがあります。 lock_guardでは、それについて考える必要はありません。

これに代わる方法があります。スコープを離れるとステートメントを実行するいくつかのSCOPE_EXIT makros(詳しくはBOOSTまたは私のお気に入りfolly/ScopeGuardを参照してください)。あなたがまだRAIIクラス(lock_guardのような)を持っていないなら、それらはもっと便利です。

現代のC++(shared_ptrunique_ptrなど)には、この他にもいくつかの例があります。一般的には、は、より堅牢なコードを持ち、エラーが発生しにくい手動アプローチよりもRAIIの実装がであることをお勧めします。

関連する問題