1

我正在尝试创建一个简单的酒吧程序,其中一定数量的客户可以同时在酒吧内。每次客户要啤酒时,调酒师都应该为客户提供啤酒。

出于某种原因,在我的程序中,酒吧服务员在顾客离开酒吧后为顾客服务

我怎样才能解决这个问题?有什么建议么?

这是我的代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> //for declaration of exit()
#include <semaphore.h> //to use semaphores

pthread_mutex_t serve = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t barrier1;
sem_t OktoEnter;

int cid = 0;

void EnterBar();
void OrderStart();
void ServeStart();
void ServeDone();
void OrderDone();
void DrinkBeer();
void LeaveBar();

void* Bartender(void *arg)
{
    ServeStart();
    ServeDone();
}

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

}

void EnterBar(){
    printf("Customer %d enters the bar.\n", cid);
    int cups;
    pthread_t order;

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

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

}
void DrinkBeer(){
    printf("Customer %d drinks the beer.\n", cid);
}
void LeaveBar(){
    printf("Customer %d leaves the bar.\n", cid);
    //increase semaphore
}

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

void ServeDone(){
    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){
        pthread_t threads[num_customers];
        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);
                rc = pthread_create(&threads[t], NULL, Customer, (void* )t);
                if (rc){
                    printf("ERROR; return code from pthread_create() is %ld\n", rc);
                    exit(-1);
                }
        }
    }
    else{
            printf("ERROR: Both parameters should be a valid positive numbers.");
            exit(-1);
    }

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

我一直在改变功能,但它不能正常工作。

4

2 回答 2

3

老实说,不清楚你最初是否清楚地知道你要从哪里开始,或者只是迷失在杂草中,你开始把东西扔到墙上看看会粘住什么。对不起,混合的比喻。

您有一堆小错误(例如,有时 cid 是一个参数,有时它是所有线程共享的全局变量)和一堆不必要的东西,我认为这是实验的碎屑。

我将它剥离为一个非常基本的线程程序,我将把它留在那里,因为我真的不明白你到底想把它放在哪里。先让简单的东西发挥作用,然后再增加复杂性。祝你好运。

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

void EnterBar();
void OrderStart();
void ServeStart();
void ServeDone();
void OrderDone();
void DrinkBeer();
void LeaveBar();

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

void* Customer(void* id)
{
    int cid = (int) id;

    EnterBar(cid);
    LeaveBar(cid);
}

void EnterBar(int cid)
{
    printf("Customer %d enters the bar.\n", cid);
    int cups;
    pthread_t order;

    OrderStart(cid);
    OrderDone(cid);
    DrinkBeer(cid);
}

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

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;

    if (argc < 3)
    {
        printf("use the parameters\n");
        exit(1);
    }

    int num_customers = atoi(argv[1]); //number of customers
    int capacity = atoi(argv[2]);      //bar capacity

    if (num_customers <= 0 || capacity <= 0)
    {
        printf("ERROR: Both parameters should be a valid positive numbers.");
        exit(1);
    }

    pthread_t threads[num_customers];

    for (t = 0; t < num_customers; t++)
    {
        printf("In main: creating thread %d\n", t);
        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);

    pthread_exit(NULL);
}
于 2012-07-03T02:06:18.157 回答
1

首先,这是一个了解线程以及生活是如何多线程的很棒的小项目。

上述场景存在问题。首先,你们都没有通过 EnterBar() 和 LeaveBar() 函数跟踪酒吧中有多少客户。在这些函数中,您需要跟踪当前柱数。一旦酒吧已满,您必须锁上门,以免其他顾客进入。然后,当顾客离开酒吧时,他们必须解锁门,以便至少再有一位顾客可以进入。此外,考虑到完整的问题场景,您应该只创建一个调酒师(即一个调酒师线程)并使用 pthread_cond_wait/pthread_cond_signal 与他同步,以便在客户要求时倒啤酒。您不能只为要倒的每种饮料而杀死并重新创建调酒师,并且记住一次只能有一个顾客要啤酒。

于 2012-07-03T14:38:59.853 回答