pthread_cond_wait の前に条件チェックが必要なのはなぜですか? 質問する

pthread_cond_wait の前に条件チェックが必要なのはなぜですか? 質問する

私はpthread_cond_waitの基本を学ぼうとしています。すべての使用法の中で、私はどちらかを見ます

if(cond is false)
   pthread_cond_wait

または

while(cond is false)
   pthread_cond_wait

私の質問は、条件が偽であるためにのみ cond_wait を実行したいということです。では、なぜ if/while ループを明示的に配置するという苦労をする必要があるのでしょうか。if/while チェックを事前に行わないと、cond_wait直接それにヒットし、まったく戻らなくなることは理解できます。条件チェックは、この目的を解決するためだけのものですか、それとも他の意味がありますか。不要な条件待機を解決するためであれば、条件チェックを配置して cond_wait を回避することは、ポーリングに似ていますか? 私はこのように cond_wait を使用しています。

void* proc_add(void *name){
    struct vars *my_data = (struct vars*)name;
    printf("In thread Addition and my id = %d\n",pthread_self());
    while(1){
    pthread_mutex_lock(&mutexattr);
    while(!my_data->ipt){  // If no input get in
            pthread_cond_wait(&mutexaddr_add,&mutexattr);  // Wait till signalled
            my_data->opt = my_data->a + my_data->b;
            my_data->ipt=1;
            pthread_cond_signal(&mutexaddr_opt);
    }
    pthread_mutex_unlock(&mutexattr);
    if(my_data->end)
            pthread_exit((void *)0);
    }
}

ロジックとしては、入力が利用可能になるたびに入力スレッドにデータを処理するように要求し、出力スレッドにそれを印刷するように信号を送ります。

ベストアンサー1

pthread_cond_waitwhile ループが必要なのは、待機している条件に達していない場合でも、呼び出したスレッドが起動する可能性があるためです。この現象は「スプリアス ウェイクアップ」と呼ばれます。

これはバグではなく、条件変数の実装方法の問題です。

これは man ページにも記載されています:

pthread_cond_timedwait() または pthread_cond_wait() 関数からの誤ったウェイクアップ発生する可能性があるpthread_cond_timedwait() または pthread_cond_wait() からの戻り値はこの述語の値について何も意味しないので、述語はそのような戻り時に再評価される必要がある

実際のコードに関する更新:

void* proc_add(void *name) 
{
    struct vars *my_data = (struct vars*)name;

    printf("In thread Addition and my id = %d\n",pthread_self());

    while(1) {

        pthread_mutex_lock(&mutexattr);

        while(!my_data->ipt){  // If no input get in
            pthread_cond_wait(&mutexaddr_add,&mutexattr);  // Wait till signalled
        }

        my_data->opt = my_data->a + my_data->b;
        my_data->ipt=1;
        pthread_cond_signal(&mutexaddr_opt);

        pthread_mutex_unlock(&mutexattr);

        if(my_data->end)
            pthread_exit((void *)0);
        }
    }
}

おすすめ記事