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() 関数からバーにいる顧客の数を追跡していません。これらの関数では、現在のバー カウントを追跡する必要があります。バーがいっぱいになったら、他の顧客が入らないようにドアをロックする必要があります。次に、顧客がバーを出るときに、ドアのロックを解除して、少なくとももう 1 人の顧客が入店できるようにする必要があります。また、完全な問題シナリオを考えると、1 つのバーテンダー (つまり、1 つのバーテンダー スレッド) のみを作成し、pthread_cond_wait/pthread_cond_signal を使用して彼と同期し、顧客がビールを要求したらビールを注ぐ必要があります。飲み物が注がれるたびにバーテンダーを殺して作り直すことはできません。また、一度にビールを頼むことができる顧客は 1 人だけであることを覚えておいてください。

于 2012-07-03T14:38:59.853 に答える