Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > pthread_cond погите разобраться


Автор: kosmonaFFFt 29.11.2008, 13:44
Доброго времени суток.

Чет я не могу разобраться с событиями в pthread, в частности в pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *)
а именно - нафига там нужен мьютекс, что с ним происходит при вызове функции и как это можно использовать применительно
к задаче о обедающих философах. Рылся в нете, но так ничего толком и не понял. :(

Пытаюсь решить задачу про философов таким способом:
Код

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

#define PHILOSOFERS_COUNT 5

//Массив потоков, символизирующих философов.
pthread_t array_of_philosofer [PHILOSOFERS_COUNT];

//Массив мьютексов, символизирующих вилки.
pthread_mutex_t array_of_mutex [PHILOSOFERS_COUNT];

//Массив событий.
pthread_cond_t array_of_cond [PHILOSOFERS_COUNT];

//Массив чисел, с номерами философов, ибо не знает философ своего номера.
int number_of_philosofer [PHILOSOFERS_COUNT];

//Функция сия эмулирует филосовское поведение, то есть эмулируемый философ может пищу поглощать или думать.
void * philosopher_eat_or_think(void * pnumber) {
    int number = *((int *)pnumber);   //А здесь философ узнает свой номер.
    while (1) {
        if (!(rand() % 2) == 0) //Философ думает.
        {
            printf("Filosof %d dumaet...\n", number);
            sleep(15);
        }
        else  //Философ ест.
        {
            printf("Filosof %d jdet osvobojdeniya levoi vilki...\n", number);
            pthread_mutex_lock(&(array_of_mutex[number]));
            pthread_cond_wait(&(array_of_cond[number]), &(array_of_mutex[number]));
            printf("Filosof %d jdet osvobojdeniya pravoi vilki...\n", number);
            if (number == 0) {
                pthread_mutex_lock(&(array_of_mutex[PHILOSOFERS_COUNT - 1]));
                pthread_cond_wait(&(array_of_cond[PHILOSOFERS_COUNT - 1]), &(array_of_mutex[PHILOSOFERS_COUNT - 1]));
            }
            else {
                pthread_mutex_lock(&(array_of_mutex[number - 1]));
                pthread_cond_wait(&(array_of_cond[number - 2]), &(array_of_mutex[number - 1]));
            }
            printf("Filosof %d est...\n", number);
            sleep(10);
            printf("Filosof %d poel...\n", number);
            pthread_mutex_unlock(&(array_of_mutex[number]));
            pthread_cond_signal(&(array_of_cond[number]));
            if (number == 0) {
                pthread_mutex_unlock(&(array_of_mutex[PHILOSOFERS_COUNT - 1]));
                pthread_cond_signal(&(array_of_cond[PHILOSOFERS_COUNT - 1]));
            }
            else {
                pthread_mutex_unlock(&(array_of_mutex[number - 1]));
                pthread_cond_signal(&(array_of_cond[number - 1]));
            }
        }
    }
    return 0;
}

int main(int argc, char * * argv) {
    int index;
    for (index = 0; index < PHILOSOFERS_COUNT; ++index) {
        number_of_philosofer[index] = index;
        pthread_mutex_init(&(array_of_mutex[index]), NULL);
        pthread_cond_init(&(array_of_cond[index]), NULL);
        pthread_create(&(array_of_philosofer[index]), NULL, philosopher_eat_or_think, &(number_of_philosofer[index]));
    }
    for (index = 0; index < PHILOSOFERS_COUNT; ++index) {
        pthread_cond_broadcast(&(array_of_cond[index]));
    }
    getchar();
    for (index = 0; index < PHILOSOFERS_COUNT; ++index) {
        pthread_mutex_destroy(&(array_of_mutex[index]));
        pthread_cond_destroy(&(array_of_cond[index]));
    }
    return 0;
}


После запуска не один философ не может начать есть.

Заранее спасибо.

Автор: MAKCim 29.11.2008, 14:23
а так
Код

void * philosopher_eat_or_think(void * pnumber) {
    int number = *((int *)pnumber);   //А здесь философ узнает свой номер.
    while (1) {
        if (!(rand() % 2) == 0) //Философ думает.
        {
            printf("Filosof %d dumaet...\n", number);
            sleep(15);
        }
        else  //Философ ест.
        {
            printf("Filosof %d jdet osvobojdeniya levoi vilki...\n", number);
            pthread_mutex_lock(&(array_of_mutex[number]));
            // pthread_cond_wait(&(array_of_cond[number]), &(array_of_mutex[number]));
            printf("Filosof %d jdet osvobojdeniya pravoi vilki...\n", number);
            if (number == PHILOSOFERS_COUNT - 1) {
                pthread_mutex_lock(&(array_of_mutex[0]));
                //pthread_cond_wait(&(array_of_cond[PHILOSOFERS_COUNT - 1]), &(array_of_mutex[PHILOSOFERS_COUNT - 1]));
            }
            else {
                pthread_mutex_lock(&(array_of_mutex[number + 1]));
                //pthread_cond_wait(&(array_of_cond[number - 2]), &(array_of_mutex[number - 1]));
            }
            printf("Filosof %d est...\n", number);
            sleep(10);
            printf("Filosof %d poel...\n", number);
            pthread_mutex_unlock(&(array_of_mutex[number]));
            //pthread_cond_signal(&(array_of_cond[number]));
            if (number == PHILOSOFERS_COUNT - 1) {
                pthread_mutex_unlock(&(array_of_mutex[0]));
                //pthread_cond_signal(&(array_of_cond[PHILOSOFERS_COUNT - 1]));
            }
            else {
                pthread_mutex_unlock(&(array_of_mutex[number + 1]));
                //pthread_cond_signal(&(array_of_cond[number - 1]));
            }
        }
    }
    return 0;
}

Автор: kosmonaFFFt 2.12.2008, 20:13
Так конечно же работает, но по заданию надо чтобы философы синхронизировались именно с помощью событий. Так пока и не придумал как это можно сделать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)