使用信号量的睡觉理发师

时间:2014-02-18 04:24:41

标签: c multithreading thread-sleep synchronisation

我在线程同步方面遇到了问题。我试图以不同的方式实施睡眠理发师问题。 当我运行代码时,线程以完全模糊的方式运行。 当我向线程添加连接时,进程逐个运行,这不是必需的。 我知道睡眠理发师问题的解决方案,但任何人都可以告诉我这个代码有什么问题。?

谢谢

#include<stdio.h>
#include<pthread.h>
#include<time.h>
#include <unistd.h>
#include<semaphore.h>
#define n 1
#define n1 50
int status[n];
int b=0;
sem_t mutex;
sem_t barber;
void *barb()
{
printf("Barber Sleeping\n");
b=1;
sem_wait(&barber);
printf("Barber woke up\n");
sleep(1);
b=0;
}
void *handler(void *ptr)
{
int x; 
    x = *((int *) ptr);
int flag=0;
int i=0;
int cnt=0;
for(i=0;i<n;i++)
{
    if(status[i]==1)
    {
    flag=1;
    cnt++;      
    }
}
printf("Count=%d",cnt);
if(cnt==n)
{
    printf("%d Customer Returned\n",x);
    return 0;
}
if(flag==1)
{
    status[x]=1;
    printf("%d Customer waiting\n",x); 
    sem_wait(&mutex);
}
if(b==1)
{
    printf("Customer %d woke up barber",x);
    sem_post(&barber);
}   
printf("Cutting Hair of customer %d\n",x);
status[x]=1;
sleep(5);
flag=0;
for(i=0;i<n;i++)
{
    if(status[i]==1)
    {
        flag=1;     
    }
}
status[x]=0;
printf("Finished cutting Hair of customer %d\n",x);
if(flag==1) 
sem_post(&mutex);
}
int main()
{
sem_init(&mutex, 0, n);
sem_init(&barber, 0, 1);
pthread_t thread[n1];
pthread_t barber;
int i=0;
for(i=0;i<n;i++)
{
    status[i]=0;
}

pthread_create(&barber,NULL,barb,NULL);
pthread_join(barber,NULL);
for(i=0;i<n1;i++)
{
    sleep(1);
    printf("Customer entered %d\n",i);
    pthread_create(&thread[i], NULL, handler, (void *)&i);
    //pthread_join(thread[i],NULL);
}
for(i=0;i<n1;i++)
{
    //pthread_join(thread[i],NULL);
}
//sem_post(&barber);

}

1 个答案:

答案 0 :(得分:0)

我有帮助你的代码

    #define _REENTRANT

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

#include <pthread.h>
#include <semaphore.h>

// The maximum number of customer threads.
#define MAX_CUSTOMERS 25

// Function prototypes...
void *customer(void *num);
void *barber(void *);

void randwait(int secs);

// Define the semaphores.

// waitingRoom Limits the # of customers allowed 
// to enter the waiting room at one time.
sem_t waitingRoom;   

// barberChair ensures mutually exclusive access to
// the barber chair.
sem_t barberChair;

// barberPillow is used to allow the barber to sleep
// until a customer arrives.
sem_t barberPillow;

// seatBelt is used to make the customer to wait until
// the barber is done cutting his/her hair. 
sem_t seatBelt;

// Flag to stop the barber thread when all customers
// have been serviced.
int allDone = 0;

int main(int argc, char *argv[]) {
    pthread_t btid;
    pthread_t tid[MAX_CUSTOMERS];
    long RandSeed;
    int i, numCustomers, numChairs;
    int Number[MAX_CUSTOMERS];


    // Check to make sure there are the right number of
    // command line arguments.
    if (argc != 4) {
    printf("Use: SleepBarber <Num Customers> <Num Chairs> <rand seed>\n");
    exit(-1);
    }

    // Get the command line arguments and convert them
    // into integers.
    numCustomers = atoi(argv[1]);
    numChairs = atoi(argv[2]);
    RandSeed = atol(argv[3]);

    // Make sure the number of threads is less than the number of
    // customers we can support.
    if (numCustomers > MAX_CUSTOMERS) {
    printf("The maximum number of Customers is %d.\n", MAX_CUSTOMERS);
    exit(-1);
    }

    printf("\nSleepBarber.c\n\n");
    printf("A solution to the sleeping barber problem using semaphores.\n");

    // Initialize the random number generator with a new seed.
    srand48(RandSeed);

    // Initialize the numbers array.
    for (i=0; i<MAX_CUSTOMERS; i++) {
    Number[i] = i;
    }

    // Initialize the semaphores with initial values...
    sem_init(&waitingRoom, 0, numChairs);
    sem_init(&barberChair, 0, 1);
    sem_init(&barberPillow, 0, 0);
    sem_init(&seatBelt, 0, 0);

    // Create the barber.
    pthread_create(&btid, NULL, barber, NULL);

    // Create the customers.
    for (i=0; i<numCustomers; i++) {
    pthread_create(&tid[i], NULL, customer, (void *)&Number[i]);
    }

    // Join each of the threads to wait for them to finish.
    for (i=0; i<numCustomers; i++) {
    pthread_join(tid[i],NULL);
    }

    // When all of the customers are finished, kill the
    // barber thread.
    allDone = 1;
    sem_post(&barberPillow);  // Wake the barber so he will exit.
    pthread_join(btid,NULL);    
}

void *customer(void *number) {
    int num = *(int *)number;

    // Leave for the shop and take some random amount of
    // time to arrive.
    printf("Customer %d leaving for barber shop.\n", num);
    randwait(5);
    printf("Customer %d arrived at barber shop.\n", num);

    // Wait for space to open up in the waiting room...
    sem_wait(&waitingRoom);
    printf("Customer %d entering waiting room.\n", num);

    // Wait for the barber chair to become free.
    sem_wait(&barberChair);

    // The chair is free so give up your spot in the
    // waiting room.
    sem_post(&waitingRoom);

    // Wake up the barber...
    printf("Customer %d waking the barber.\n", num);
    sem_post(&barberPillow);

    // Wait for the barber to finish cutting your hair.
    sem_wait(&seatBelt);

    // Give up the chair.
    sem_post(&barberChair);
    printf("Customer %d leaving barber shop.\n", num);
}

void *barber(void *junk) {
    // While there are still customers to be serviced...
    // Our barber is omnicient and can tell if there are 
    // customers still on the way to his shop.
    while (!allDone) {

    // Sleep until someone arrives and wakes you..
    printf("The barber is sleeping\n");
    sem_wait(&barberPillow);

    // Skip this stuff at the end...
    if (!allDone) {

        // Take a random amount of time to cut the
        // customer's hair.
        printf("The barber is cutting hair\n");
        randwait(3);
        printf("The barber has finished cutting hair.\n");

        // Release the customer when done cutting...
        sem_post(&seatBelt);
    }
    else {
        printf("The barber is going home for the day.\n");
    }
    }
}

void randwait(int secs) {
    int len;

    // Generate a random number...
    len = (int) ((drand48() * secs) + 1);
    sleep(len);
}