Поскольку вы хотите знать how to code your algorithm for 1 restroom
, я сделал это в C. Это будет довольно простая задача, чтобы превратить его в C--, так как все семафоры конструкции появляются очень похожи.
Из того, что я мог бы сделать из вашего ответа,
C: sem_wait() C--: wait()
sem_post() signal()
sem_t semaphore()
sem_init() initialsem()
Имейте в виду, как было сказано, я выработал эту проблему только 1-уборной. Поскольку это домашнее задание, я ожидаю, что вы расширите его в 2-туалетах сформируйте себя.
Работа свой путь от Readers-writers problem к нашей проблеме «Унисекс Restroom», мы используем следующие глобальные переменные:
int mcount,wcount; // count of number of men/women in restroom
sem_t x,y,z; // semaphores for updating mcount & wcount values safely
sem_t wsem,msem; // semaphores to block other genders' entry
sem_t cap; // capacity of the restroom
Объединив эти семафоры & счетчиков в функции man
нити,
void *man(void *param)
{
sem_wait(&z);
sem_wait(&msem);
sem_wait(&x);
mcount++;
if(mcount==1)
{ sem_wait(&wsem); } // first man in, make women wait
sem_post(&x);
sem_post(&msem);
sem_post(&z);
sem_wait(&cap); //wait here, if over capacity
printf("\t\tman in!\n");
delay();
printf("\t\t\tman out!\n");
sem_post(&cap); //one man has left, increase capacity
sem_wait(&x);
mcount--;
if(mcount==0)
{sem_post(&wsem);} // no man left, signal women
sem_post(&x);
}
Аналогично, функция женской нити, заменяет mcount
на wcount
, msem
с wsem
и x
с y
. Только z
остается как есть в функции man
, так что оба man
& woman
потоки очереди на одном общем семафоре.(В связи с этим, код всегда имеет FIFO-как поведение, которое обеспечивает справедливость/не голодание)
Полный код выглядит следующим образом: (компилировать, использовать gcc filename -lpthread
)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int mcount,wcount;
sem_t x,y,z,wsem,msem,cap;
void delay(void)
{
int i;
int delaytime;
delaytime = random();
for (i = 0; i<delaytime; i++);
}
void *woman(void *param)
{
sem_wait(&z);
sem_wait(&wsem);
sem_wait(&y);
wcount++;
if(wcount==1)
{ sem_wait(&msem); }
sem_post(&y);
sem_post(&wsem);
sem_post(&z);
sem_wait(&cap);
printf("woman in!\n");
delay();
printf("\twoman out!\n");
sem_post(&cap);
sem_wait(&y);
wcount--;
if(wcount==0)
{ sem_post(&msem); }
sem_post(&y);
}
void *man(void *param)
{
sem_wait(&z);
sem_wait(&msem);
sem_wait(&x);
mcount++;
if(mcount==1)
{ sem_wait(&wsem); }
sem_post(&x);
sem_post(&msem);
sem_post(&z);
sem_wait(&cap);
printf("\t\tman in!\n");
delay();
printf("\t\t\tman out!\n");
sem_post(&cap);
sem_wait(&x);
mcount--;
if(mcount==0)
{sem_post(&wsem);}
sem_post(&x);
}
int main(void)
{
int i;
srandom(60);
mcount = 0;
wcount = 0;
sem_init(&x,0,1); // for sem_init, initial value is 3rd argument
sem_init(&y,0,1);
sem_init(&z,0,1);
sem_init(&wsem,0,1);
sem_init(&msem,0,1);
sem_init(&cap,0,4); // eg. cap initialized to 4
pthread_t *tid;
tid = malloc(80*sizeof(pthread_t));
// You can use your cobegin statement here, instead of pthread_create()
// I have forgone the use of pthread barriers although I suppose they would nicely imitate the functionality of cobegin.
// This is merely to retain simplicity.
for(i=0;i<10;i++)
{
pthread_create(&tid[i],NULL,woman,NULL);
}
for(i=10;i<20;i++)
{
pthread_create(&tid[i],NULL,man,NULL);
}
for(i=0;i<20;i++)
{
pthread_join(tid[i],NULL);
}
return(0);
}
При преобразовании в 2-туалета форму, обратите внимание на семафоры & переменные счетчика, которые необходимо будет дублировать, чтобы удовлетворить все условия. Happy семафорование!
ли это быть оптимальным? –
Нет. Но у него не может быть голода. Таким образом, мужчины и женщины должны правильно пользоваться туалетом. – Jen
Я не уверен, что вы беспокоитесь о голоде, но я уверен, что ваш алгоритм имеет проблему голодания. Представьте себе случай, когда один мужчина появляется, пока женщина уже находится в ванной, и постоянный поток женщин продолжает появляться, так что ванная комната никогда не опустошается. –