3

私はこのようなマルチスレッドプログラムを書きました、

#include <queue>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>

using namespace std;

pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ec = PTHREAD_COND_INITIALIZER;
pthread_cond_t fc = PTHREAD_COND_INITIALIZER;

queue<int> qu;
const int N = 2;

void *producer(void *arg)
{
    while(1) {
        pthread_mutex_lock(&mu);
        int tmp = rand();
        qu.push(tmp);
        pthread_cond_signal(&ec);
        if ((int) qu.size() > N) {
            pthread_cond_wait(&fc, &mu);
        }
        pthread_mutex_unlock(&mu);
    }
}

void *consumer(void *arg)
{
    while(1) {
        pthread_mutex_lock(&mu);
        if ((int) qu.size() < 1) {
            pthread_cond_wait(&ec, &mu);
        }
        int tmp = qu.front();
        qu.pop();
        if ((int) qu.size() <= N) {
            pthread_cond_signal(&fc);
        }
        pthread_mutex_unlock(&mu);
        //sleep(1);
    }
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, producer, NULL);
    for (int i = 0; i < N; i++) {
        pthread_t tid;
        pthread_create(&tid, NULL, consumer, NULL);
    }

    printf("all created\n");

    sleep(600);
}

qu.size()がgeaterより大きい場合は、N生成producerを停止する必要があり、がより小さい場合はNproducer生成を再開します。

奇妙な問題は、を削除するsleep(1);consumerプログラムが実行されsegmentation fault、保持するとプログラムが正常に実行されることsleep(1);です。

なんで?consumer消費が速すぎるということですか?

4

2 に答える 2

4

偽のウェイクアップが理由かもしれません。条件が真の場合、スレッドは続行しますが、スレッドが進行した場合、条件が真であると想定することはできません。

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

だから例えば

if (qu.size() == 0) {
    pthread_cond_wait(&ec, &mu);
}

になる必要があります

while (qu.size() == 0) {
    pthread_cond_wait(&ec, &mu);
}
于 2012-07-29T11:50:47.690 に答える
1

あなたがsleep(1)電話を続けて、すべてがクラッシュしないなら、あなたはただ幸運です:)

pthread_mutex_init()を使用して明示的にミューテックスを初期化してみてください。そうしないと、pthread_mutex_lock()呼び出しが失敗するように見えます。

ドキュメントから:

Errors

The pthread_mutex_lock() and pthread_mutex_trylock()
functions may fail if: 

EINVAL: The value specified by mutex
does not refer to an initialized mutex object.
于 2012-07-29T11:44:48.983 に答える