信号量和并发编程

时间:2010-10-03 00:31:06

标签: c concurrency semaphore

对于家庭作业,我需要编写以下场景。这将使用信号量使用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之间的某个数字。

  • 以良好的方式打印和格式化输出,并以这样的方式打印消息:通过读取输出,可以跟踪执行顺序。
  • 将进程设置为永久循环,并使用控件C(或控制中断)来停止程序。

3 个答案:

答案 0 :(得分: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-restroom 的问题。由于这是家庭作业,我希望您自己将其扩展为 2-restrooms 形式。

Readers-writers problem到“男女皆宜的洗手间”问题的工作方式,我们使用以下全局变量:

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

合并这些信号量&amp;计数器进入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函数中,因此manwoman gcc filename -lpthread个线程在同一个公共信号量上排队。 (因此,代码总是具有类似FIFO的行为,这可确保公平/非饥饿

完整代码如下:(要编译,请使用#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); }

{{1}}

在转换为 2-restrooms 表单时,请记下哪些信号量&amp;您需要复制的计数器变量才能满足所有条件。快乐 semaphoring

答案 1 :(得分:0)

这就是我所拥有的。这允许一个人在洗手间一次没有死锁或饥饿。我需要协助如何制作它,这样一下四个人就可以进入洗手间。

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

答案 2 :(得分: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();
}
      }