Семафоры и параллельное программирование - PullRequest
7 голосов
/ 03 октября 2010

Для выполнения домашнего задания мне нужно запрограммировать следующий сценарий.Это будет сделано с использованием семафоров с использованием 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.

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

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

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

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

Ответы [ 3 ]

1 голос
/ 08 октября 2010

Поскольку вы хотите знать how to code your algorithm for 1 restroom, я сделал это на C. Это будет довольно простой задачей для преобразования его в C--, так как все конструкции семафоров выглядят очень похоже.

Fromчто я могу сделать из вашего ответа,

C: sem_wait()  C--: wait()
   sem_post()       signal()
   sem_t            semaphore()
   sem_init()       initialsem() 

Помните, как я уже говорил, я решил проблему только для 1-туалета .Поскольку это домашнее задание, я ожидаю, что вы расширите его до 2-комнат отдыха формы самостоятельно.

Проложите свой путь от проблемы Читатели-писатели к нашему "Унисекс"Проблема уборки », мы используем следующие глобальные переменные:

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 голосов
/ 28 февраля 2011

для 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();
}
      }
0 голосов
/ 03 октября 2010

Вот что у меня есть.Это позволяет 1 человеку в туалете за один раз без тупика или голода.Мне нужна помощь в том, как сделать так, чтобы в туалете одновременно могли находиться 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...