спящий парикмахер дает тупик

Я написал код для проблемы со спящим парикмахером, и он выглядит странно ... код выглядит следующим образом ..

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

#define MAX_C 10
int a[MAX_C], head=0, tail=0, tmp, tb, tc, count=1;
pthread_mutex_t B;
double time_slot[]={0.125,0.5,0.75,1.00,1.25,1.50,1.75,2.00};

void wait(int a)
{
    clock_t g=clock();
    while(((float)(clock()-g))/CLOCKS_PER_SEC != time_slot[a]);
}

void barber()
{
    printf("barber started\n");
    while(1) {
        tmp=0;
        while(head==tail) {
            printf("b\n");
        }
        tb=rand()%8;
        printf("tail:%d\n", tail);
        tail=(tail+1)%MAX_C;
        wait(tb);
    }
}

void customer()
{       
    printf("customers started\n");
    while(1) {
        wait(rand()%8);
        while((head+1)%MAX_C == tail) {
            printf("c\n");
        }
        a[head]=count-1;
        printf("head:%d\n", head);
        head=(head+1)%MAX_C;
    }
}

int main(int argc, char* argv[])
{
    pthread_t b,c;

    pthread_mutex_init(&B, NULL);
    pthread_create(&c, NULL, (void*)&customer, NULL);
    pthread_create(&b, NULL, (void*)&barber, NULL);

    pthread_join(b, NULL);
    pthread_join(c, NULL);  
    exit(0);
}

Проблема в том, что когда буфер заполнен ... парикмахер ждет клиентов ... но клиент вообще не выполняет !! (он не ожидает и не заполняет буфер) ... потому что клиенты, в то время как цикл был не выполняется ...


person nitish712    schedule 28.08.2012    source источник
comment
Прототипы ваших потоковых функций должны быть void* function (void*)   -  person mathematician1975    schedule 28.08.2012
comment
Кроме того, это не может быть тупиковой ситуацией как таковой, поскольку вы никогда не блокируете свой мьютекс в любом месте, которое я могу видеть.   -  person mathematician1975    schedule 28.08.2012
comment
Он вообще входит в customer? Т.е. выполняется ли первая printf инструкция? Вы пробовали запустить его в отладчике, поставить точку останова в customer и пройти через него, чтобы увидеть, что происходит?   -  person Some programmer dude    schedule 28.08.2012
comment
@ mathematician1975 Я думаю, что это совсем не проблема ... и, конечно, я не знаю, как назвать эту проблему ...   -  person nitish712    schedule 28.08.2012
comment
@Joachim Я запустил его, и функция клиента выполняется ...   -  person nitish712    schedule 28.08.2012
comment
Вы изменяете 2 глобальные переменные без синхронизации, и эти переменные используются для управления логикой контура. Ваш код в его нынешнем виде невозможно предсказать осмысленным образом. Возможно, вам стоит подумать о мьютексе, защищающем ваш код при изменении head и tail. Если, конечно, я чего-то не понимаю ...   -  person mathematician1975    schedule 28.08.2012
comment
Да, я тоже пробовал это ... На самом деле я думаю, что мьютексы следует использовать только тогда, когда два процесса пытаются получить доступ к одной и той же переменной ... здесь этого не происходит ...   -  person nitish712    schedule 28.08.2012
comment
С while(((float)(clock()-g))/CLOCKS_PER_SEC != time_slot[a]) ожидание может быть довольно долгим, если ОС запускается в неподходящее время. Возможно, вам стоит вместо этого протестировать < time_slot[a].   -  person Daniel Fischer    schedule 28.08.2012
comment
@nitish - Но они имеют доступ как к head, так и tail, как в while(head==tail).   -  person Bo Persson    schedule 28.08.2012
comment
@BoPersson, это не имело никакого значения ... (сохраняете ли вы мьютекс или нет ...), я все еще получаю то же самое ...   -  person nitish712    schedule 28.08.2012
comment
@DanielFischer также не будет ошибкой писать так ... потому что мы сравниваем jst разницу между тактами часов, которая не зависит от того, работает ли поток или остается в состоянии сна ...   -  person nitish712    schedule 28.08.2012
comment
@ nitish712 (Очень) Маловероятно, но если while пропустит правильное значение clock(), он будет зацикливаться, пока не завершится (если clock_t - интегральный тип, конец света, если clock_t тип с плавающей запятой). Использование < просто немного более защитное.   -  person Daniel Fischer    schedule 28.08.2012
comment
@Daneil Тогда почему это происходит именно после заполнения всего буфера ??   -  person nitish712    schedule 29.08.2012


Ответы (2)


Как сказал Данил Фишер ... с while(((float)(clock()-g))/CLOCKS_PER_SEC != time_slot[a]); произошла ошибка, я должен заменить ее на

while(((float)(clock()-g))/CLOCKS_PER_SEC <= time_slot[a]);

Но все же странно, что это «пропадание» значения часов происходит только после того, как весь буфер заполнен ...

person nitish712    schedule 29.08.2012

У вас есть проблема с семафорами, которые исполняющий модуль использует ЦП.

Пожалуйста, посмотрите, хорошо ли вы используете семафоры. Не забывайте #include

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

#include <pthread.h>
#include <semaphore.h>

// The maximum number of customer threads.
#define MAX_CUSTOMERS 25
</b>

void *customer(void *number) {
    int num = *(int *)number;

    // Leave for the shop and take some random amount of
    // time to arrive.
    printf("Customer %d leaving for barber shop.\n", num);
    randwait(5);
    printf("Customer %d arrived at barber shop.\n", num);

    // Wait for space to open up in the waiting room...
    sem_wait(&waitingRoom);
    printf("Customer %d entering waiting room.\n", num);

    // Wait for the barber chair to become free.
    sem_wait(&barberChair);

    // The chair is free so give up your spot in the
    // waiting room.
    sem_post(&waitingRoom);

    // Wake up the barber...
    printf("Customer %d waking the barber.\n", num);
    sem_post(&barberPillow);

    // Wait for the barber to finish cutting your hair.
    sem_wait(&seatBelt);

    // Give up the chair.
    sem_post(&barberChair);
    printf("Customer %d leaving barber shop.\n", num);
}

void *barber(void *junk) {
    // While there are still customers to be serviced...
    // Our barber is omnicient and can tell if there are 
    // customers still on the way to his shop.
    while (!allDone) {

    // Sleep until someone arrives and wakes you..
    printf("The barber is sleeping\n");
    sem_wait(&barberPillow);

    // Skip this stuff at the end...
    if (!allDone) {

        // Take a random amount of time to cut the
        // customer's hair.
        printf("The barber is cutting hair\n");
        randwait(3);
        printf("The barber has finished cutting hair.\n");

        // Release the customer when done cutting...
        sem_post(&seatBelt);
    }
    else {
        printf("The barber is going home for the day.\n");
    }
    }
}
person Paulo Rodrigues    schedule 27.12.2015