надлежащая реализация производитель-потребитель - PullRequest
1 голос
/ 28 октября 2011

Я пытаюсь реализовать модель производитель-потребитель, и у меня возникли некоторые проблемы с ней. Считайте код

int number=0;

void* master(void* p){
    int i;
    pthread_t workers[5];
    for(i=0;i<5;i++)
        pthread_create(&workers[i],NULL,worker,NULL);

    while(1){
        //possible delay

        pthread_mutex_lock(&mutex);
        if(number == LIMIT)
            pthread_cond_wait(&not_full,&mutex);

        number++;
        pthread_cond_signal(&not_empty);
        pthread_mutex_unlock(&mutex);
    }
}

void* worker(void* p){
    while(1){
        pthread_mutex_lock(&mutex);
        if(number == 0)
            pthread_cond_wait(&not_empty,&mutex);

        number--;
        pthread_cond_signal(&not_full);
        pthread_mutex_unlock(&mutex);

        //possible delay
    }
}

Может быть, это очевидно для вас, но я не могу понять, как возможно, что переменная номер становится отрицательной, что, конечно, позволяет рабочему потоку уменьшать его дальше. Что я делаю не так?

- EDIT -

Хорошо, один прогресс выполняется в то время как (число == 0) вместо if, но я до сих пор не понимаю, как могло получиться, что два потока могут уменьшить переменную после получения сигнала not_empty, пока он меньше двух .

1 Ответ

2 голосов
/ 28 октября 2011

Я думаю, что замена if with while может маскировать проблему, а не решать ее.По Почему функциям условных переменных pthreads требуется мьютекс? мьютекс, который вы используете с условной переменной, используется для защиты доступа к этой условной переменной.В вашем случае вы, кажется, используете mutex для защиты трех вещей: глобальной number и двух условных переменных not_full и not_empty.

Что-то, что вам нужно реализовать - реализацияof pthread_cond_wait () разблокирует ваш мьютекс и снова заблокирует его, прежде чем он вернется, и это открытое окно позволяет другим потокам входить, когда вы этого не хотите.Замените, если на то время как у вас есть, это одно решение, но другое использует второй мьютекс в вашем работнике для защиты доступа как к «номеру», так и к условному ожиданию.

...