2010-10-03 3 views
7

Для выполнения домашнего задания мне необходимо запрограммировать следующий сценарий. Это делается с использованием семафоров с использованием BACI (который является C--)Семафоры и параллельное программирование

Есть 2 унисекса, которые могут вмещать 4 человека. Поскольку это унисекс, люди одного пола могут одновременно находиться в туалете, а FIFO не имеет значения. У меня есть основной «алгоритм» в моей голове, чтобы обращаться с 4 мужчинами и 4 женщинами за 1 уборную. Но я не знаю, как это кодировать. Любая помощь будет принята с благодарностью. Вот что у меня есть.

Woman: 

Check to see if there are any men in the restroom. If so "wait". 
If no men check to see if there are 4 people. If so "wait". 
If no men and not 4 use restroom. When leaving signal there is a vacancy. 
If last woman signal the men if they are waiting if not signal the woman. 


Man: 

check to see if there are any woman in the restroom. if so "wait" 
If no woman check to see if there are 4 people. If so "wait". 
If no woman and not 4 use restroom. when leaving signal there is a vacancy. 
if last man signal the women if they are waiting if not signal the men. 

Эти дополнительные инструкции были предоставлены

  • Использование случайным образом для циклов, чтобы имитировать ход времени в соответствующих местах. Это можно легко сделать с помощью функции задержки:

    void Delay (void) 
    { 
        int i; 
        int DelayTime; 
        DelayTime = random (DELAY); 
        for (i = 0; i < DelayTime; i++): 
    } 
    
  • где Const INT DELAY = некоторое число от 10 до 100.

  • печати и формат вывода красиво и печать сообщений таким образом, что при чтении на выходе можно отслеживать порядок выполнения.
  • Установите процессы на цикл навсегда и используйте управление C (или прерывание управления), чтобы остановить вашу программу.
+0

ли это быть оптимальным? –

+0

Нет. Но у него не может быть голода. Таким образом, мужчины и женщины должны правильно пользоваться туалетом. – Jen

+0

Я не уверен, что вы беспокоитесь о голоде, но я уверен, что ваш алгоритм имеет проблему голодания. Представьте себе случай, когда один мужчина появляется, пока женщина уже находится в ванной, и постоянный поток женщин продолжает появляться, так что ванная комната никогда не опустошается. –

ответ

0

Вот что у меня есть. Это позволяет одному человеку в туалете одновременно без тупика или голода. Мне нужна помощь в том, как сделать так, чтобы 4 человека могли находиться в туалете за раз.

const int Delayx = 60; 
int i; 
semaphore max_capacity; 
semaphore woman; 
semaphore man; 
semaphore mutex; 

void Delay(void) 
{ 
    int DelayTime; 
    DelayTime = random(Delayx); 
    for (i = 0; i<DelayTime; i++); 
} 

void Woman(void) 
{ 
    wait(woman); 
    wait(max_capacity); 
    wait(mutex); 
    cout << "A Woman has entered Restroom"<<endl; 
    Delay(); 
    cout << "A woman has exited Restroom"<<endl; 
    signal(mutex); 
    signal(max_capacity); 
    signal(man); 
} 

void Man(void) 
{ 
    wait(man); 
    wait(max_capacity); 
    wait(mutex); 
    cout <<"A Man has entered the Restroom"<<endl; 
    Delay(); 
    cout << "A man has exited the Restroom"<<endl; 
    signal(mutex); 
    signal(max_capacity); 
    signal(woman); 
} 

void main() 
{ 
    initialsem(woman,1); 
    initialsem(man,1); 
    initialsem(max_capacity,4); 
    initialsem(mutex,1); 
    cobegin 
    { 
     Woman(); Woman(); Woman(); Woman(); Woman(); Woman(); Woman(); Woman(); Man(); Man(); Man(); Man(); Man(); Man(); Man(); Man(); 
    } 
} 
1

Поскольку вы хотите знать 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 семафорование!

0

для 4 уборной кода Baci:

const int Delayx = 60; 
    int i; 
    int Mcount,Wcount; 
    binarysem x,y,z,Wsem,Msem; 
    semaphore cap; 
    void Delay(void) 
    { 
    int DelayTime; 
    DelayTime = random(Delayx); 
    for (i = 0; i<DelayTime; i++); 
    } 

void Woman(void) 
    { 
    wait(z); 
    wait(Wsem); 
    wait(y); 
    Wcount++; 
    if(Wcount==1) 
     { wait(Msem); } 
     signal(y); 
     signal(Wsem); 
     signal(z); 

     wait(cap); 
     cout << "A Woman has entered Restroom"<<endl; 
     Delay(); 
     cout << "A Woman has exited Restroom"<<endl; 

     signal(cap); 
     wait(y); 
     Wcount--; 
     if(Wcount==0) 
     {signal(Msem);} 

     signal(y); 
     } 

void Man(void) 
    { 
    wait(z); 
    wait(Msem); 
    wait(x); 
    Mcount++; 
    if(Mcount==1) 
     { wait(Wsem); } 
     signal(x); 
     signal(Msem); 
     signal(z); 

     wait(cap); 
     cout << "A Man has entered Restroom"<<endl; 
     Delay(); 
     cout << "A Man has exited Restroom"<<endl; 

     signal(cap); 
     wait(x); 
     Mcount--; 
     if(Mcount==0) 
     {signal(Wsem);} 

     signal(x); 
     } 


void main() 
{ 
Mcount=0; 
Wcount=0; 
initialsem(x,1); 
initialsem(y,1); 
initialsem(z,1); 
initialsem(Wsem,1); 
initialsem(Msem,1); 
initialsem(cap,4); 
cobegin 
{ 
    Woman(); Woman(); Woman(); 
    Woman(); Woman(); Woman(); 
    Woman(); 
    Woman(); Man(); Man(); 
    Man(); Man(); Man(); Man(); 
    Man(); Man(); 
} 
     } 
Смежные вопросы