-1

マルチスレッド環境でのマップの読み取り、書き込み、削除の3つの機能があります。それで、それらは正常に動作しますか?または、マルチスレッドプログラムでマップから読み取り、書き込み、および削除したいデッドロックまたはその他の種類のエラーを作成します。

//Function for read 
string GetData (const int key)
{

    pthread_rwlock_rdlock(&rwlock); //read lock
    string result = "not found";
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
        result = iter->second;
    }
    else //missing
    {
        // change from read mode to write mode
        pthread_rwlock_unlock(&rwlock); // unlock read lock
        pthread_rwlock_wrlock(&rwlock); // write lock
        // Try again
        iter = m.find(key);
        if (iter != m.end()) {
            result = iter->second;
        }
        else
        {
        string = "";
        }
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
}

//Function for write
void SetData (const int key)
{

    pthread_rwlock_rdlock(&rwlock); //read lock
    string result = "not found";
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
        result = iter->second;
    }
    else //missing
    {
        // change from read mode to write mode
        pthread_rwlock_unlock(&rwlock); // unlock read lock
        pthread_rwlock_wrlock(&rwlock); // write lock
        // Try again
        iter = m.find(key);
        if (iter != m.end()) {
            result = iter->second;
        }
        else
        {
            m[key] = "missing data";
            result = "missing data";
        }
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
}
//Function for delete
//Function for write
void deleteData (const int key)
{
    pthread_rwlock_rdlock(&rwlock); //read lock
    string result = "not found";
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
        result = iter->second;
    }
    else //missing
    {
        // change from read mode to write mode
        pthread_rwlock_unlock(&rwlock); // unlock read lock
        pthread_rwlock_wrlock(&rwlock); // write lock
        // Try again
        iter = m.find(key);
        if (iter != m.end()) {
            my_map->erase(iter);
        }
        else
        {
        }
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
}
4

2 に答える 2

0

コードに干渉して例外をスローしないミューテックスがにない限り、問題はなく、デッドロックは発生しません。

CスタイルのコードとC++を組み合わせると、例外が最悪の敵になります。std::mutexC ++ 11とを調べることをお勧めしますstd::lock_guardが、手動で修正することもできます。簡単な解決策については、以下を参照してください。もっとエレガントな方法もありますが、重要なのは何らかの方法でそれを処理することです。

他のミューテックスはどうですか?my_mapあなたの例では、それがユーザー定義型(一部の標準コンテナーではない)であり、メンバー関数findなどもミューテックスを内部的にロックする場合、それらは型に隠れることができます。他の場合(あなたの例ではありません)、値はUDTであり、intミューテックスを使用するだけではありません。

あなたのコードについて奇妙なことの1つ:なぜGetDataミューテックスを書き込みロックでロックするのですか?それは不必要で非効率的なようです。また、他の関数については、すぐに書き込みロックを取得し、一般に読み取りロックの取得をスキップします。ただし、どちらも有効なユースケースであり、両方とも潜在的なパフォーマンス上の利点がある可能性があるため、一方をプロファイリングすることをお勧めします。

また、ミューテックスを操作するときは、可能であれば常にコードをロックされたセクションの外に移動してください。そうは言っても、次のようにGetDataなります。

string GetData (const int key)
{
  string result = "not found"; // moved before the lock
  pthread_rwlock_rdlock(&rwlock); //read lock
  try {
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
      result = iter->second;
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
  }
  catch( ... ) {
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    throw;
  }
}
于 2013-03-08T05:47:33.797 に答える
0

コードにはほとんど問題がありません。だから私には見えます。

  1. 例:deleteData; 読み取りロックの下にレコードが見つかった場合、それをどのように処理していますか?削除しませんか?書き込み関数についても同じことが言えます。
  2. なぜ書き込みおよび削除機能で読み取りロックを取得するのですか?すぐに書き込みロックを取得してみませんか?
  3. 読んで、なぜあなたはとにかく書き込みロックを取っているのですか?

私によると、擬似コードは

読み取り-読み取りロックを取得-検索。結果の保存-見つかったか見つかりません。-ロックを解除します-戻ります

書き込み-書き込みロックを取得-書き込み。既存のキーを上書きするかどうかを決定します。上書きしない場合は何を返しますか?ほとんどの標準実装は上書きするように設定されています。-ロックを解除します-戻ります

あなたの一般的なアプローチは良いです-問題はありません。

1つのロックだけでデッドロックを発生させることはできません。デッドロックが発生するには、少なくとも2つのロックと特定のパターンが必要です。例えば

スレッド1ロック(A)ロック(B)

スレッド2ロック(B)ロック(A)

上記は、スレッド1が最初のロック呼び出しの直後にスワップアウトし、スレッド2が開始した場合、デッドロックにつながる可能性があります。

それよりもエキゾチックになり、他の潜在的な問題について心配したい場合は、たとえば、優先順位の逆転について心配することができます。ほとんどの場合、あなたはそれについて考える必要さえないので、私はエキゾチックと言っています。

于 2013-03-08T05:48:33.467 に答える