信号量和并发编程

发布于 2024-09-26 04:55:18 字数 1148 浏览 1 评论 0原文

对于家庭作业,我需要编写以下场景。这将通过使用 BACI(即 C--)的信号量来完成。

有 2 个男女通用的卫生间,每个可容纳 4 人。由于它是男女通用的,所以只有同性别的人可以同时进入卫生间,先进先出并不重要。我脑子里有一个基本的“算法”,可以处理 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 循环在适当的位置模拟时间的流逝。这可以通过使用 Delay 函数轻松完成:

    无效延迟(无效)
    { 
      整数我;
      int 延迟时间;
      延迟时间=随机(DELAY);
      for (i = 0; i < DelayTime; i++):
    }
    
  • where const int DELAY = 10 到 100 之间的某个数字。

  • 很好地打印和格式化输出并打印消息通过读取输出,可以跟踪执行顺序。
  • 将进程设置为永远循环,并使用 Control C(或 Control Break)来停止程序。

For a homework assignment i need to program the following scenario. This is going to be done using semaphores using BACI (which is C--)

There are 2 unisex restrooms that can hold 4 people each. Since it is unisex only people of the same sex can be in the restroom at the same time and FIFO is not important. I have the basic "algorithm" in my head to handle 4 men and 4 woman for 1 restroom. But i don't know how to code this. Any help would be greatly appreciated. Here is what I have.

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.

These additional instructions were provided

  • Use random FOR loops to simulate the passage of time in the appropriate places. This can be easily done by using a Delay function:

    void Delay (void)
    { 
      int i;
      int DelayTime;
      DelayTime = random (DELAY);
      for (i = 0; i < DelayTime; i++):
    }
    
  • where const int DELAY = some number from 10 to 100.

  • Print and format output nicely and print messages in such a way that by reading the output, one can trace the execution order.
  • Set the processes up to loop forever, and use control C (or control break) to stop your program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅黛梨妆こ 2024-10-03 04:55:18

由于您想知道如何为 1 个卫生间编写算法,我已经用 C 语言编写了代码。将其转换为 C 语言将是一个相当简单的任务,因为所有信号量结构看起来都很简单相似的。

根据我对您的回答的理解,

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,以及xy。只有 z 保留在 man 函数中,因此 manz 都保持原样。 线程在同一个公共信号量上排队。 (因此,代码总是具有类似 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-restrooms 形式时,记下哪些信号量和信号量您需要复制计数器变量才能满足所有条件。快乐信号传递

Since you want to know how to code your algorithm for 1 restroom, I have done so in C. It will be a fairly simple task to convert it into C--, as all the semaphore constructs appear quite similar.

From what I could make of your answer,

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

Bear in mind, as stated, I have worked out the problem for 1-restroom only. Since this is homework, I expect you to expand it into the 2-restrooms form yourself.

Working one's way from the Readers-writers problem to our "Unisex Restroom" problem, we make use of the following global variables:

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

Incorporating these semaphores & counters into the man thread function,

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);
}

Similarly, the woman thread function, substitutes mcount with wcount, msem with wsem, and x with y. Only z remains as is in the man function, so that both man & woman threads queue up on the same common semaphore. (Due to this, the code invariably has FIFO-like behaviour, which ensures fairness/non-starvation)

The complete code is as follows: (To compile, use 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);
}

While converting into the 2-restrooms form, make note of which semaphores & counter variables you would need to duplicate to satisfy all the conditions. Happy semaphoring!

你丑哭了我 2024-10-03 04:55:18

这是我所拥有的。这使得一次可以有 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();
    }
}

Here is what I have. This allows 1 person in the restroom at a time without deadlock or starvation. I'm in need of assistance with how to make it so 4 people can be in the restroom at a time.

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();
    }
}
想挽留 2024-10-03 04:55:18

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();
}
      }

for 4 restroom baci code :

 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();
}
      }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文