0

所以我设法让我的程序运行,但由于某种原因,除非他/她之前的顾客先离开酒吧,否则没有顾客走进酒吧,我该如何解决?我尝试了一个 mutex_lock 但我可能实施错了,这是我到目前为止的代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem;
pthread_mutex_t serve = PTHREAD_MUTEX_INITIALIZER;

void Bartender(int);
void EnterBar(int);
void OrderStart(int);
void ServeStart(int);
void ServeDone(int);
void OrderDone(int);
void DrinkBeer(int);
void LeaveBar(int);
void* Customer(void*);

void Bartender(int cid)
{
    ServeStart(cid);
    ServeDone(cid);
}

void* Customer(void* id)
{
    int cid =(int)id;
    EnterBar(cid);
    LeaveBar(cid);
    return NULL;

}

void EnterBar(int cid){
    sem_wait(&sem); //decrease semaphore
    printf("Customer %d enters the bar.\n", cid);
    int cups;

    for(cups=0;cups<(cid%3+1);cups++){
        pthread_mutex_lock(&serve);     
        OrderStart(cid);
        OrderDone(cid);
        DrinkBeer(cid);     
        pthread_mutex_unlock(&serve);
    }
}
void OrderStart(int cid)
{
    printf("Customer %d asks for beer.\n", cid);
    Bartender(cid);
}

void OrderDone(int cid)
{
    printf("Customer %d gets the beer.\n", cid);
}

void DrinkBeer(int cid)
{
    printf("Customer %d drinks the beer.\n", cid);
}

void LeaveBar(int cid)
{
    printf("Customer %d leaves the bar.\n", cid);
    sem_post( &sem ); //increase semaphore
}

void ServeStart(int cid)
{
    printf("Bartender starts to serve customer %d.\n", cid);
}

void ServeDone(int cid)
{
    printf("Bartender is done serving customer %d.\n", cid);
}

int main (int argc, char *argv[])
{
    int t;
    long rc;    
    int num_customers = atoi(argv[1]); //number of customers
    int capacity = atoi(argv[2]); //bar capacity

    if(num_customers > 0 && capacity > 0){
        rc = sem_init( &sem, 0, capacity );
        if (rc)
        {
            printf("ERROR; return code from sem_init() is %ld\n",rc);
            exit(-1);
        }
        //pthread_t threads[num_customers];
        pthread_t *threads = (pthread_t*)malloc(num_customers*sizeof(pthread_t));
        if(random() > RAND_MAX / 2)
            usleep(1);
        //rc = sem_init(&sem1,0,capacity);
        //rc = pthread_barrier_init(&barrier1, NULL, num_customers);
        for(t=0; t<num_customers;t++){
                printf("In main: creating thread %d\n", t);
            //printf("CAPACITY: %d\n", capacity);
                rc = pthread_create(&threads[t], NULL, Customer, (void* )t);
                if (rc){
                    printf("ERROR; return code from pthread_create() is %ld\n", rc);
                    exit(-1);
                }
        }
        for( t=0;t<num_customers;t++)
            pthread_join(threads[t],NULL);

        sem_destroy(&sem); //destroy semaphore
    }
    else{
            printf("ERROR: Both parameters should be a valid positive numbers.");
            exit(-1);
    }

    /* Last thing that main() should do */
    pthread_exit(NULL);
}

它应该允许酒吧里的多个顾客,并在喝完啤酒后离开,而不是在顾客离开之前离开。调酒师需要一根线吗?有什么建议么??

4

4 回答 4

2
#include <unistd.h>

并修改此功能

void DrinkBeer(int cid)
{
    printf("Customer %d drinks the beer for 10 seconds.\n", cid);
    sleep(10);
}
void LeaveBar(int cid)
{
    printf("Customer %d leaves the bar (takes 10 sec).\n", cid);
    sem_post( &sem ); //increase semaphore
   sleep(10);
}

看看它现在的行为。您需要一些睡眠功能,以便线程可以睡眠并更好地观察其他线程的工作方式。它是否可以通过这些修改发挥应有的作用?

于 2012-07-05T22:26:57.583 回答
1

我认为这是一个正确的行为,对吧?客户 2 是酒吧的第一个,但在客户 1 之后离开。

[amb@localhost ~]$ ./a.out 3 2
In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
Customer 2 enters the bar.
Customer 2 asks for beer.
Bartender starts to serve customer 2.
Bartender is done serving customer 2.
Customer 2 gets the beer.
Customer 2 drinks the beer for 7 seconds.
Customer 1 enters the bar.
Customer 1 asks for beer.
Bartender starts to serve customer 1.
Bartender is done serving customer 1.
Customer 1 gets the beer.
Customer 1 drinks the beer for 8 seconds.
Customer 2 asks for beer.
Bartender starts to serve customer 2.
Bartender is done serving customer 2.
Customer 2 gets the beer.
Customer 2 drinks the beer for 6 seconds.
Customer 1 asks for beer.
Bartender starts to serve customer 1.
Bartender is done serving customer 1.
Customer 1 gets the beer.
Customer 1 drinks the beer for 4 seconds.
Customer 1 leaves the bar.
Customer 0 enters the bar.
Customer 0 asks for beer.
Bartender starts to serve customer 0.
Bartender is done serving customer 0.
Customer 0 gets the beer.
Customer 0 drinks the beer for 6 seconds.
Customer 2 asks for beer.
Bartender starts to serve customer 2.
Bartender is done serving customer 2.
Customer 2 gets the beer.
Customer 2 drinks the beer for 7 seconds.
Customer 0 leaves the bar.
Customer 2 leaves the bar.
于 2012-07-05T23:00:11.733 回答
1

没有你认为你有的问题。我做了以下更改。

(1) //添加全局变量

int count = 0;
pthread_mutex_t mutCount = PTHREAD_MUTEX_INITIALIZER;

(2) 添加到吧台人数并打印出来

void EnterBar(int cid)
{
    sem_wait(&sem); //decrease semaphore

    printf("Customer %d enters the bar.\n", cid);    

    pthread_mutex_lock(&mutCount);
    count++;
    printf("There are %i customers in the bar\n", count);
    pthread_mutex_unlock(&mutCount);

    int cups;

    for (cups = 0;cups < (cid % 3 + 1);cups++)
    {
        pthread_mutex_lock(&serve);
        OrderStart(cid);
        OrderDone(cid);
        DrinkBeer(cid);
        pthread_mutex_unlock(&serve);
    }
}

(3) 当他们离开时减少酒吧里的顾客数量

void LeaveBar(int cid)
{
    printf("Customer %d leaves the bar.\n", cid);

    pthread_mutex_lock(&mutCount);
    count--;
    pthread_mutex_unlock(&mutCount);

    sem_post( &sem ); //increase semaphore
}

(4) 主要改变睡到有价值的事情上

    if (random() > RAND_MAX / 2)
        usleep(100);

(5) 我跑了:barthread 20 15 | grep “有”

(6) 我得到以下输出:

There are 1 customers in the bar
There are 2 customers in the bar
There are 1 customers in the bar
There are 3 customers in the bar
There are 4 customers in the bar
There are 5 customers in the bar
There are 6 customers in the bar
There are 7 customers in the bar
There are 6 customers in the bar
There are 6 customers in the bar
There are 5 customers in the bar
There are 5 customers in the bar
There are 5 customers in the bar
There are 6 customers in the bar
There are 4 customers in the bar
There are 4 customers in the bar
There are 5 customers in the bar
There are 6 customers in the bar
There are 7 customers in the bar
There are 8 customers in the bar
于 2012-07-05T23:59:00.217 回答
1

所有这些互斥锁是怎么回事?几个信号量有什么问题,一个“barAccess”,初始化为条形容量,一个“barStaff”,初始化。调酒师的数量?

#define slaughtered (beerCount==10)

{
  beerCount=0;
  wait(barAccess);
  do{
    wait(barStaff);
    sleep(pouringTime);
    signal(barstaff);
    sleep(drinkingTime);
    beerCount++;
  }while(!slaughtered);
  signal(barAccess);
};

如果这个酒吧有常客,你可以添加另一个 while(true) 循环,用 'sleep(soberUp);' 环绕它。在酒窖中的每个会话之后。

在营业时间内改变酒吧员工的数量也很容易。只需添加更多“barStaff”单位或偷走一些。

如果它真的很忙,您可能还想打开酒廊酒吧以增加容量 - 只是所有更多的 barAccess 单元在一个循环中。

关门时间应该很有趣。你需要说服顾客离开,不要再让他们进来。如果顾客没有在合理的时间内得到服务,也许他们应该离开。然后,您可以吸走所有的酒吧工作人员,这样顾客就无法得到服务,并聚集在所有的 barAccess 单元中,这样新顾客就无法进入。最终,今天的酒吧将是空的。当您第二天开门时,先挤进酒吧工作人员,然后挤进酒吧访问单位,然后看着急于上菜!

于 2012-07-06T04:43:16.197 回答