在C中进行多线程处理时,同步无法正常工作

时间:2012-07-03 00:50:54

标签: c linux synchronization pthreads mutex

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

出于某种原因,在我的计划中,酒吧招标在他/她离开酒吧后为客户服务

我该如何解决这个问题?有什么建议吗?

这是我的代码:

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

我一直在努力改变功能,但它无法正常工作。

2 个答案:

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

答案 1 :(得分:1)

首先,这是了解线程以及生命多线程的一个很好的小项目。

上述方案存在问题。首先,你们两个都没有跟踪EnterBar()和LeaveBar()函数中栏中有多少客户。在这些功能中,您需要跟踪当前的条数。一旦酒吧已满,您必须锁上门,以便其他客户无法进入。然后当顾客离开酒吧时,他们必须解锁门,这样至少还有一个顾客可以进入。此外,鉴于完整的问题情况,您应该只创建一个调酒师(即一个调酒师线程)并使用pthread_cond_wait / pthread_cond_signal与他同步以在客户要求时倒入啤酒。你不能只是为每一杯倒酒而继续杀戮并重新打造酒保,并且记住每次只有一位顾客可以要求喝啤酒。这应该都是用pthread_mutex_lock / unlock's完成的。