私はCのposixスレッドを使用しています。問題が発生しました。私はそれほど理解しておらず、何が問題なのかを知りたいです。pthread mutexが待ち状態でロック解除していません
要約すると、私は3つのスレッドを作成して、プログラムの状態を確認し、準備ができていることを知らせ、さらに信号を待っています。一方、これらのスレッドを作成したスレッドは、それぞれのスレッドがセットアップされたことを通知するために待機しています(pthread_cond_wait_)。しかし、一度待ってからプログラムが完全に停止すると、ミューテックスは決してロックされないようです。
これは、メインスレッドのコードです:ここで
pthread_mutex_lock(&scenario->mutex);
if (scenario->flags.sinkThreadSetup == 0) {
pthread_create(&sinkT, NULL, sinkProblemHandler, (void *)scenario);
pthread_cond_wait(&scenario->sinkSetupCondition, &scenario->mutex);
}
if (scenario->flags.freeThreadSetup == 0) {
pthread_create(&freeT, NULL, freeWheelProblemHandler, (void *)scenario);
pthread_cond_wait(&scenario->freeSetupCondition, &scenario->mutex);
}
if (scenario->flags.blockThreadSetup == 0) {
pthread_create(&blockT, NULL, blockProblemHandler, (void *)scenario);
pthread_cond_wait(&scenario->blockSetupCondition, &scenario->mutex);
}
scenario->state = VECTORING;
pthread_mutex_unlock(&scenario->mutex);
// Start wheel threads
pthread_t wheelThreads[NUM_WHEELS];
scenario_wheel_t threadDataArr[NUM_WHEELS];
for (int i =0; i < NUM_WHEELS; i++) {
threadDataArr[i].scenario = scenario;
threadDataArr[i].wheel = &scenario->wheels[i];
pthread_create(&wheelThreads[i], NULL, wheel_start, (void *)&threadDataArr[i]);
}
pthread_mutex_lock(&scenario->mutex);
pthread_cond_wait(&scenario->scenarioComplete_condition, &scenario->mutex);
pthread_mutex_unlock(&scenario->mutex);
は、問題のハンドラスレッドのコードです:
void *sinkProblemHandler(void *args) {
scenario_t *scenario = (scenario_t *) args;
while(scenario->flags.terminate != 1) {
pthread_mutex_lock(&scenario->mutex);
if (scenario->state == SETUP && scenario->flags.sinkThreadSetup == 0) {
scenario->flags.sinkThreadSetup = 1;
pthread_cond_signal(&scenario->sinkSetupCondition);
}
if (scenario->state != SINKING) {
pthread_cond_wait(&scenario->conditions.sinking_condition, &scenario->mutex);
if (scenario->flags.terminate == 1) {
pthread_mutex_unlock(&scenario->mutex);
pthread_exit(NULL);
}
printf("SINKHandler: I'M HELPING!");
}
pthread_mutex_unlock(&scenario->mutex);
}
pthread_exit(NULL);
}
void *blockProblemHandler(void *args) {
scenario_t *scenario = (scenario_t *) args;
while(scenario->flags.terminate != 1) {
pthread_mutex_lock(&scenario->mutex);
if (scenario->state == SETUP && scenario->flags.blockThreadSetup == 0) {
scenario->flags.blockThreadSetup = 1;
pthread_cond_signal(&scenario->blockSetupCondition);
}
if (scenario->state != BLOCKED) {
pthread_cond_wait(&scenario->conditions.blocked_condition, &scenario->mutex);
if (scenario->flags.terminate == 1) {
pthread_mutex_unlock(&scenario->mutex);
pthread_exit(NULL);
}
printf("BlockHandler: I'M HELPING!");
}
pthread_mutex_unlock(&scenario->mutex);
}
pthread_exit(NULL);
}
void *freeWheelProblemHandler(void * args) {
scenario_t *scenario = (scenario_t *) args;
while(scenario->flags.terminate != 1) {
pthread_mutex_lock(&scenario->mutex);
if (scenario->state == SETUP && scenario->flags.freeThreadSetup == 0) {
scenario->flags.freeThreadSetup = 1;
pthread_cond_signal(&scenario->freeSetupCondition);
}
if (scenario->state != BLOCKED) {
pthread_cond_wait(&scenario->conditions.freeWheeling_condition, &scenario->mutex);
if (scenario->flags.terminate == 1) {
pthread_mutex_unlock(&scenario->mutex);
pthread_exit(NULL);
}
printf("FreeHandler: I'M HELPING!");
}
pthread_mutex_unlock(&scenario->mutex);
}
pthread_exit(NULL);
}
我々は問題ハンドラスレッドがそれぞれのセットアップを知らせることをここで見ることができます条件を満たしてから別の条件(pthread_cond_wait)を待つと、mutexのロックが解除されます。
私の初期の考えは、メインスレッドが待機を開始する前に問題ハンドラスレッドがシグナリングしていたため、デッドロックが発生するということでした。しかし、プログラムに接続した後では、プログラムは次のようになります。
1.問題のスレッドを開始します。
2.問題セットアップ条件(ロック解除ミューテックス)を待ちます。
3.問題ハンドラスレッドロックミューテックス。
3.問題ハンドラスレッドがシグナルを完了しました
4.問題ハンドラスレッドが待機します(おそらくmutexのロックを解除します)。
5.プログラムが完全に停止します。 (mutexがロックされていないなど)。
ご協力いただければ幸いです。 おかげ
私が奇妙なのはあなたのメインプログラムの 'pthread_mutex_lock(&scenario-> mutex);'です。同じことをするスレッドでデッドロックが発生する可能性があります。 –
メインスレッドのコードの最後には、他のすべてのスレッドが条件変数を待っているのを中断しています...そして、メインスレッドはmutexをロックして、条件を待っています。自分の条件で待っている。 (またはそれが現れる...私は何かを見逃していないことを確認するために慎重に見なかった) – Dmitri
'wheel_start()'には何が入っていますか? – Dmitri