別のスレッド (生産者) が何かを作るときに、スレッド (消費者) が興味を示すことができるようにしたいと考えています。しかし、いつもではありません。
基本的にはワンショットコンシューマを作りたいと思っています。理想的には、プロデューサーは、1 人 (または多数) のコンシューマーが何かを欲しがっているというシグナルを出すまで、そのビジネスについて陽気に進みます。コンシューマーは、変数が満たされるまで待機します。
また、ワンショット コンシューマーが待機時間が長すぎると判断し、待機を放棄できるようにする必要もあります (a la pthread_cond_timedwait
) 。
スレッドを同期するさまざまな方法について、多くの記事と SO の質問を読んできました。現在、私は条件変数アプローチに傾倒しています。
これが良い方法なのか (スレッド プログラミングの初心者なので、おそらくかなりの数のバグが含まれている可能性があります)、またはこの状況でセマフォを (乱用) 使用する方がよいかどうかを知りたいですか? それともまったく別のものですか?可能であれば、ポインター変数へのアトミック代入だけですか? おそらく私は安全な側に留まろうとしているからでしょう.このアプリケーションはロックアップすることなく何ヶ月も実行されるはずです. プロデューサーのミューテックスなしでできますか? つまり、条件変数を通知するだけですか?
私の現在のコードは次のようになります。
consumer {
pthread_mutex_lock(m);
pred = true; /* signal interest */
while (pred) {
/* wait a bit and hopefully get an answer before timing out */
pthread_cond_timedwait(c, m, t);
/* it is possible that the producer never produces anything, in which
case the pred will stay true, we must "designal" interest here,
unfortunately the also means that a spurious wake could make us miss
a good answer, no? How to combat this? */
pred = false;
}
/* if we got here that means either an answer is available or we timed out */
//... (do things with answer if not timed out, otherwise assign default answer)
pthread_mutex_unlock(m);
}
/* this thread is always producing, but it doesn't always have listeners */
producer {
pthread_mutex_lock(m);
/* if we have a listener */
if (pred) {
buffer = "work!";
pred = false;
pthread_cond_signal(c);
}
pthread_mutex_unlock(m);
}
注: 私は最新の Linux を使用しており、必要に応じてプラットフォーム固有の機能を利用できます。 注 2: 一見グローバル変数 m、c、および t を使用しました。しかし、これらは消費者ごとに異なります。
概要の要約
スレッドがイベントに登録し、指定された時間待機してから続行できるようにしたい。理想的には、複数のスレッドが同時に登録でき、すべてのスレッドが同じイベント (タイムスパンに発生したすべてのイベント) を取得できる必要があります。