複数のプロデューサー/コンシューマーおよびクリティカルセクションコードの問題
-
05-07-2019 - |
質問
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を他のスレッドと同時に実行することはできません。
所属していません StackOverflow