複数のプロデューサー/コンシューマーおよびクリティカルセクションコードの問題

StackOverflow https://stackoverflow.com/questions/1408047

質問

Cで複数の生産者/消費者の問題を試みていますが、期待どおりに機能しません。以下は、実装を表すための擬似コードです。

Thread thread1;
Thread thread2;
Thread thread3;

Data data1;
Mutex data1_mutex;
Semaphore data1_empty;
Semaphore data1_fill;

Data data2;
Mutex data2_mutex;
Semaphore data2_empty;
Semaphore data2_fill;

thread1()
{
   // creates data and places it into data1.

   wait(data1_empty);
   lock(data1_mutex);

   // critical section

   unlock(data1_mutex);
   post(data1_fill);
}

thread2()
{
   // Removes data from data1, processes it, and places it into data2.

   // data1
   wait(data1_fill);
   lock(data1_mutex);

   // data2
   wait(data2_empty);
   lock(data2_mutex);

   // critical section

   // data2
   unlock(data2_mutex);
   post(data2_fill);

   // data1
   unlock(data1_mutex);
   post(data1_empty);
}

thread3()
{
   // Removes data from data2, prints its results, and removes it.

   wait(data2_fill);
   lock(data2_mutex);

   // critical section

   unlock(data2_mutex);
   post(data2_empty);
}

ただし、このソリューションではdata1がいっぱいになりますが、thread2はロックされ、実行されません。私の実装に何か問題がありますか?

編集#1

見つかった問題の1つは、2番目のミューテックスが正しく作成されていなかったことです。何が悪いのかわかりませんので、すべてのスレッドに最初のミューテックスを使用しています。それを機能させるために私がやったこともありますので、しばらくしてからこれを反映するように擬似コードを更新します。

役に立ちましたか?

解決

最初に data1_empty および data2_empty を必ず投稿してください。

他のヒント

Data に何らかのキューイングタイプを使用する場合、「空」を削除できるはずです。セマフォは、各 Data キュー深度が厳密に0または1であるという条件を課そうとしない限り、完全にセマフォです。 thread2 でローカル変数を使用する場合、クリティカルセクションのサイズ。

コードは次のようになります:

thread1() {
    //Wait for data to put in the queue (i.e. a blocking socket read)
    lock(data1_mutex);
    data1.push(someData);
    unlock(data1_mutex);
    post(data1_fill);
}

thread2() {
    DataType dataElement;
    wait(data1_fill);
    lock(data1_mutex);
    dataElement = data1.pop();
    unlock(data1_mutex);

    lock(data2_mutex);
    data2.push(dataElement);
    unlock(data2_mutex);
    post(data2_fill);
}

thread3() {
    DataType dataElement;
    wait(data2_fill);
    lock(data2_mutex);
    dataElement = data2.pop();
    unlock(data2_mutex);
    //do something with dataElement here
}

wrang-wrangが言ったこと、そしてdata_2_emptyを待っている間はdata_1のロックを保持しないようにしてください。これは、スワップアウトするdata_1とdata_2の代替バッファーを保持することで実現できます。 Thread_2は、data_2への処理中にdata_1をスワップし、thread_3は、処理中にdata_2をスワップアウトします。現在の擬似コードでは、スレッド1とスレッド3を同時に実行できますが、スレッド2を他のスレッドと同時に実行することはできません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top