0

pthread とミューテックスを使用したイベントの順序付けを理解するために、次のコードを作成しました。main関数は、関数func1およびfunc2に関連付けられている 2 つのスレッドを作成します。関数func1はcountの値をチェックし、条件付きでfunc2がそれを通知するのを待ちます。関数func2はカウントをインクリメントし、countが 50000 に達するとfunc1を通知します。次に、func1は、その時点で 50000 である (またはそうあるべきである) countの値を出力します。

しかし、実際の出力では、50000 とともに他の値も出力されています。なぜそうなのか、理由がわかりません。私が思うには、func2が信号を送ると、func1が起動して pthread_cond_wait ステートメントの後から実行されるため、50000 しか出力されないはずです。どこが間違っているのか、正しい出力を得るために何を変更する必要があるのか​​を指摘してください。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


pthread_mutex_t evmutex;
pthread_cond_t evcond;

char a;
int count;
int N = 50000;

void *func1()
{
    while(1)
    {
        pthread_mutex_lock(&evmutex);
        if(count < N)
        {
            pthread_cond_wait(&evcond,&evmutex);
            printf("%d\n",count);
            count = 0;
        }
        pthread_mutex_unlock(&evmutex);


    }
}


void *func2()
{
    while(1)
    {
        pthread_mutex_lock(&evmutex);
        count++;
        if(count == N)
        {
            pthread_cond_signal(&evcond);
        }
        pthread_mutex_unlock(&evmutex);


    }
}

int main ()
{
    pthread_t ptd1,ptd2;

    pthread_mutex_init(&evmutex,NULL);
    pthread_cond_init(&evcond,NULL);
    count = 0;
    pthread_create(&ptd1,NULL,func1,NULL);
    pthread_create(&ptd2,NULL,func2,NULL);


    pthread_exit(NULL);
    pthread_mutex_destroy(&evmutex);
    pthread_cond_destroy(&evcond);

    return 0;
}
4

2 に答える 2

1

プロデューサー func2() と同期しておらず、コンシューマー func1() が条件を処理するまで待機するように指示していません。

プロデューサーが条件を通知し、ミューテックスを再取得し、カウンターを再度インクリメントすることを止めるものは何もありません。pthread_cond_signal は、プロデューサーが停止してコンシューマーが処理するのを待つという意味ではありません。これは、コンシューマーがスケジュールされ、ウェイクアップして現在の数を出力する前に、プロデューサーがカウンターを何度もインクリメントする可能性があることを意味します。

プロデューサーがカウンターを N にインクリメントした後に待機する別の条件変数を追加し、カウンターを処理したときにコンシューマーに通知する必要があります。

それに加えて、他の回答が言及しているように、偽のウェイクアップを処理する必要があります。

于 2013-02-08T23:47:09.130 に答える
0

の一部の実装でpthread_cond_wait()は、偽のウェイクアップが発生するため、これをwhile (cond) { pthread_cond_wait(...); }回避するためにループを使用するのが一般的です。

ここで問題と原因の適切な説明を見つけました: Why does pthread_cond_wait has spurious wakeups?

于 2013-02-08T23:28:37.830 に答える