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 つの「barAccess」、1 つの「barStaff」、init の何が問題になっていますか。バーテンダーの数に?

#define slaughtered (beerCount==10)

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

このバーに常連客がいる場合は、「sleep(soberUp);」を使用して別の while(true) ループを追加できます。ブザーでの各セッションの後。

営業時間中のバースタッフの数の変更も簡単です。「barStaff」ユニットを追加するか、盗んでください。

非常に混雑している場合は、ラウンジバーを開いて収容人数を増やすこともできます。ループ内の barAccess ユニットをすべて増やすだけです。

クロージングタイムが楽しくなるはずです。顧客を説得して立ち去り、それ以上入らせないようにする必要があります。適切な時間内にサービスを受けられない場合、顧客は立ち去る必要があるかもしれません。次に、顧客がサービスを受けられないようにすべてのバースタッフを吸い出し、新しい顧客が入らないようにすべての barAccess ユニットに集めることができます。最終的に、今日のバーは空になります。翌日開店したら、最初にバースタッフを押し込み、次にバーアクセスユニットを押し込み、急いで出されるのを見てください!

于 2012-07-06T04:43:16.197 に答える
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)主にusleepを何か価値のあるものに変える

    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 に答える