C中的多线程无法正常工作

时间:2012-07-05 21:45:33

标签: c linux multithreading synchronization pthreads

所以我设法让我的程序运行但是出于某种原因,没有客户走进酒吧,除非他/她之前的客户先离开酒吧,我该如何解决? 我尝试了一个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 个答案:

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

了解它现在的表现。你需要一些睡眠功能,因此线程可以睡眠并更好地观察其他线程的工作方式。 这种修改能否正常运作?

答案 1 :(得分: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.

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

答案 3 :(得分:1)

所有这些mutex gunge有什么用?一对信号量有什么问题,一个&#39; barAccess&#39;初始化为条形容量,一个&#39; barStaff&#39;,init。调剂的数量?

#define slaughtered (beerCount==10)

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

如果此栏有常规客户,您可以使用&#39; sleep(soberUp)添加另一个while(true)循环;&#39;每次在布泽尔会议之后。

在开放时间内改变酒吧的数量也很容易。只需添加更多&#39; barStaff&#39;单位或偷走一些。

如果真的很忙,你可能还想打开酒吧以增加容量 - 只需要循环中的所有barAccess单元。

关闭时间应该很有趣。您需要说服客户离开,不再允许。如果他们没有在合理的时间内获得服务,也许客户应该离开。然后你就可以吸掉所有的酒吧老板,这样客户就无法获得服务并聚集在所有的barAccess单元中,这样新的客户就无法进入。最终,今天的酒吧将是空的。当你第二天打开时,首先在酒吧里推,然后barAccess单位,并观看急于获得服务!