rendered paste body
// Prototypes
void* customer(void* num);
void* barber(void* num);
// Global Data
sem_t BtoC;
sem_t CtoB;
sem_t haircutDone;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int waitingCustomersNo = 0;
int numChairs = 0;
int numCustomers = 0;
int numBarbers = 0;
int main(int argc, char** argv)
{
pthread_t barbers_tid[100];
pthread_t customers_tid[100];
if(argc != 4)
{
printf("Usage: %s #customers #chairs #barbers\n", argv[0]);
return -1;
}
numCustomers = atoi(argv[1]);
numChairs = atoi(argv[2]);
numBarbers = atoi(argv[3]);
//Initialize semaphores:
sem_init(&BtoC, 0, 0);
sem_init(&CtoB, 0, 0);
sem_init(&haircutDone, 0, 0);
for(int i = 1; i <= numBarbers; i++)
{
if(pthread_create(&barbers_tid[i-1], NULL, barber, (void*) i) == 0)
{
//printf("Created barber #%d.\n",i);
}
else
{
printf("Failed to create barber #%d! So only %d barbers will be used.\n",i, i-1);
numBarbers = i-1;
break;
}
}
for(int i = 1; i <= numCustomers; i++)
{
if(pthread_create(&customers_tid[i-1], NULL, customer, (void*) i) == 0)
{
sleep(1);
//printf("Created customer #%d.\n",i);
}
else
{
printf("Failed to create customer #%d! So only %d customers will be used.\n",i, i-1);
numCustomers = i-1;
break;
}
}
for(int i = 0; i < numBarbers; i++)
{
pthread_join(barbers_tid[i], NULL);
}
for(int i = 0; i < numCustomers; i++)
{
pthread_join(customers_tid[i], NULL);
}
return 0;
}
void* customer(void* number)
{
int myNum = (int) number;
pthread_mutex_lock(&mutex);
printf("Customer #%d has arrived. \t\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
fflush(stdin);
if(numChairs > waitingCustomersNo)
{
waitingCustomersNo++;
printf("Customer #%d took a seat.\t\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
//pthread_mutex_unlock(&mutex);
sem_post(&CtoB);
pthread_mutex_unlock(&mutex);
printf("CUSTOMER #%d is calling wait(BtoC)\n", myNum);
sem_wait(&BtoC);
printf("Customer #%d is now receiving a haircut.\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
sem_wait(&haircutDone);
//printf("Customer #%d's haircut is done.\t\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
}
else
{
printf("Customer #%d notices there are no open seats.\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
pthread_mutex_unlock(&mutex);
}
printf("Customer #%d left the barber shop.\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
pthread_exit(NULL);
}
void* barber(void* number)
{
int myNum = (int) number;
printf("Barber #%d has arrived.\t\t\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
while(1)
{
sem_wait(&CtoB);
pthread_mutex_lock(&mutex);
//sleep(10);
waitingCustomersNo--;
if(waitingCustomersNo < 0)
{
printf("WTF?!?!?!?!\n"); //should never reach this point!
//pthread_mutex_unlock(&mutex);
}
printf("Barber #%d took the next waiting customer.\t\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
sem_post(&BtoC);
pthread_mutex_unlock(&mutex);
sleep(2);
sem_post(&haircutDone);
printf("Barber #%d is done with the haircut.\t#customers=%d seats_left=%d\n", myNum, waitingCustomersNo, numChairs-waitingCustomersNo);
}
pthread_exit(NULL);
}