0

私は Linux プログラミングに非常に慣れていないので、ご容赦ください。異なる操作を実行する 2 つのスレッド タイプがあるため、それぞれに独自のミューテックスが必要です。これが私が使用しているコードです、それは良いですか? そうでない場合、なぜですか?

static pthread_mutex_t cs_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t cs_mutex2 = PTHREAD_MUTEX_INITALIZER;

void * Thread1(void * lp)
{
    int * sock = (int*)lp;
    char buffer[2024];

    int bytecount = recv(*sock, buffer, 2048, 0);
    while (0 == 0)
    {
        if ((bytecount ==0) || (bytecount == -1))
        {
        pthread_mutex_lock(&cs_mutex);

                  //Some uninteresting operations witch plays with set 1 of global variables;
        pthread_mutex_unlock(&cs_mutex);
        }
    }
}

void * Thread2(void * lp)
{   
    while (0 == 0)
    {
        pthread_mutex_lock(&cs_mutex2);
            //Some uninteresting operations witch plays with some global variables;
        pthread_mutex_unlock(&cs_mutex2);
    }
}
4

5 に答える 5

7

通常、ミューテックスはスレッド関連ではありません。重要な領域が単一のスレッドによってのみアクセスされるようにします。したがって、複数のスレッドで同じ配列を処理するなど、いくつかの共有領域がある場合は、この領域への排他的アクセスを確保する必要があります。つまり、スレッドごとにミューテックスは必要ありません。重要な領域にはミューテックスが必要です。

于 2012-09-20T07:48:32.250 に答える
6

ドライバーが1人だけの場合、2台の車を持っていることに利点はありません。あなたのThread2コードは、を押している間だけ有用な進歩を遂げることができますcs_mutex2。したがって、そのコードを複数のスレッドで実行しても意味がありません。一度に1つのスレッドのみがミューテックスを保持でき、もう1つのスレッドは有用な作業を実行できません。

したがって、達成するのは、ミューテックスを保持していないスレッドが実行を試み、他のスレッドを待機しなければならない場合があるということだけです。また、ミューテックスを保持しているスレッドは、ミューテックスを解放して再取得しようとし、他のスレッドに取って代わられることがあります。

これは完全に無意味なスレッドの使用です。

于 2012-09-20T08:06:59.027 に答える
3

ここには 3 つの問題があります。あなたの無限ループ、複数のスレッドを持つ意図についての質問があり、将来の保守性の「落とし穴」が潜んでいます。

初め

int bytecount = recv(*sock, buffer, 2048, 0);
while (0 == 0)

そうですか?ソケットから何かを読み取り、ソケットを閉じずに無限ループを開始しますか? ループ内でさらに読み取りを行うと想定することしかできませんが、その場合、ミューテックスを保持しながら外部イベントを待機しています。一般に、これは同時実行性を制限する悪いパターンです。考えられるパターンは、1 つのスレッドがデータを読み取ってから、読み取ったデータを処理を行う他のスレッドに渡すことです。

次に、それぞれが独自のミューテックスによって保護されている 2 つの異なるリソース セットがあります。次に、リソースごとに一連のスレッドを作成します。しかし、各スレッドにはパターンがあります

   take mutex
       lots of processing
   release mutex
       tiny window (a few machine instructions)
   take mutex again
        lots of processing
   release mutex
        next tiny window

2 つのスレッドが並行して動作する機会は事実上ありません。リソースごとに複数のスレッドが必要かどうかについて質問します。

最後に、潜在的なメンテナンスの問題があります。将来の参考のためにこれを指摘しているだけで、今すぐ何もする必要はないと思います。2 つのスレッドで使用することを意図した 2 つの関数がありますが、最終的には、それらは誰でも呼び出すことができる単なる関数です。後のメンテナンスでこれらの関数 (または関数のリファクタリングされたサブセット) が発生した場合、2 つのスレッドを取得できます。

    take mutex 1
    take mutex 2

そして他の

    take mutex 2
    take mutex 1

ビンゴ:デッドロック。

回避するのは簡単な問題ではありませんが、少なくとも、慎重な命名の選択とリファクタリングによってメンテナーを助けることができます。

于 2012-09-20T08:18:07.390 に答える
2

あなたのコードは正しいと思いますが、2つのことに注意してください:

  1. 例外安全ではありません。から例外がスローされたSome uninteresting operations場合、ミューテックスのロックが解除されることはありません->デッドロック

  2. 生のミューテックスの代わりにstd::mutexまたはboost::mutexを使用することも検討できます。ミューテックスロックには、boost :: mutex :: scoped_lock(またはstd ::アナログと最新のコンパイラ)を使用することをお勧めします

    void test()
    {
        // not synch code here
        {
            boost::mutex::scoped_lock lock(mutex_);
            // synchronized code here
        }
    }
    
于 2012-09-20T07:35:37.180 に答える
2

2つの異なるデータセットと2つの異なるスレッドがこれらのセットで動作している場合、なぜミューテックスが必要なのですか?通常、ミューテックスは、共有データを処理するときに使用され、2つのスレッドが同時に処理することを望まないため、ミューテックスでロックし、いくつかの操作を行い、ロックを解除します。

于 2012-09-20T07:37:27.080 に答える