glibc pthreads ライブラリを使用してマルチスレッド アプリケーションを作成しています。私は 3 つの pthread を持っています - そのうちの 1 つは「スケジューラー」と呼ばれ、他の 2 つは「ワーカー」と呼ばれ、メインスレッドです。メイン スレッドはイベントをリッスンし、それらをキューに入れます。次に、スケジューラ スレッドがそれらをワーカー キューにディスパッチします。ワーカー スレッドは、ワーカー キューからイベントを取得して実行します。問題は、主要なデータ競合を防ぐために、メインスレッド自体でイベントを実行する必要がある場合があります。したがって、特別なイベントが受信されたときにメイン スレッドを一時停止し、すべてのワーカーがジョブを終了するまで待機してから、このイベントを実行するメカニズムが必要です。
これを行うために、ミューテックスによって保護された整数を使用します。ミューテックスのビットは、ワーカー スレッドによって設定およびリセットされます。キューにジョブが見つからない場合、ワーカーはビットを 0 に設定します。ジョブがある場合は、ビットを 1 としてマークします。ワーカーの 1 つが実行されている場合、整数は != になります。 0. メイン スレッドは、ワーカーが終了するまで一時停止する必要がある場合、整数が 0 になるまで条件付き待機を行います。ワーカー スレッドは、ビットをリセットするときに、整数が 0 になるかどうかをチェックします。true の場合、メインスレッドに通知します。この時点で、すべてのワーカーのキューにジョブがなく、メイン スレッドが特別なイベントを実行できることを期待しています。メイン スレッドがイベントを最初のキューにキューイングする役割を担っているため、ワーカーにイベントが忍び込むことはありません。
擬似コードは次のとおりです。
int pause_threads() => the one called from main thread.
{
pthread_mutex_lock(pause_thread_lock));
while (pthread_states != 0) {
pthread_cond_wait(pause_mthread_cond), pause_thread_lock));
}
}
int thread_resume() => called after the special event is executed by main thread.
{
pthread_mutex_unlock(pause_thread_lock));
}
int thread_set_state_wait(index) => index is id 0,1 for each worker
{
pthread_mutex_lock(pause_thread_lock));
(thread_states) &= (~(MTHREAD_THR_STATE_RUNNING << index));
if (pthread_states == 0)
pthread_cond_signal(pause_thread_cond));
pthread_mutex_unlock(&(pause_thread_lock));
}
int thread_set_state_running(index)
{
pthread_mutex_lock(pause_thread_lock));
(pthread_states) |= (MTHREAD_THR_STATE_RUNNING << index);
pthread_mutex_unlock(pause_thread_lock));
}
私が直面している問題は、このコードが常に機能していないことです。メイン スレッドが特別なイベントを実行している間に、ワーカー スレッドがまだアクティブでジョブを実行していることが時々あります。ロジックに何か問題がありますか?これを達成する他の方法はありますか?私は解決策を探すために最善を尽くしました。助けてください。