Created
May 6, 2017 15:20
-
-
Save mengcz13/c032ef918cf8ceb34761cc207c9a80ed to your computer and use it in GitHub Desktop.
Solution for barber problem~
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <unistd.h> | |
#include <pthread.h> | |
#include <semaphore.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#define N 10 | |
#define TN 3 | |
#define MAX_WTIME 5 | |
#define MAX_BTIME 5 | |
sem_t waiting; // ==0表示当前没有顾客等待, >0表示有顾客在等待 | |
sem_t seat; // ==1表示理发椅就绪 | |
sem_t finish; // ==1表示当前被服务顾客服务完成 | |
sem_t mutex; // 临界区标志 | |
sem_t lockseat; // ==1表示最先来到的顾客已经锁定理发椅 | |
sem_t leave; // ==1表示当前被服务顾客已经离开理发椅 | |
int waiting_num; // 当前排队人数 | |
int* table; // 记录当前等待椅状况 | |
int barber_table; // 记录当前理发椅状况 | |
void* customer(void* cid); | |
void* barber(void* bid); | |
int main(int argc, char** argv) { | |
srand(0); | |
waiting_num = 0; | |
table = (int*)(malloc(sizeof(int) * TN)); | |
memset(table, 0, sizeof(int) * TN); | |
barber_table = 0; | |
sem_init(&waiting, 0, 0); | |
sem_init(&seat, 0, 0); | |
sem_init(&finish, 0, 0); | |
sem_init(&mutex, 0, 1); | |
sem_init(&lockseat, 0, 0); | |
sem_init(&leave, 0, 0); | |
pthread_t barber_thread; | |
pthread_t* customer_threads = (pthread_t*)(malloc(sizeof(pthread_t) * N)); | |
pthread_create(&barber_thread, NULL, barber, NULL); | |
int i = 0; | |
for (; i < N; ++i) { | |
sleep(rand() % MAX_WTIME); | |
pthread_create(&customer_threads[i], NULL, customer, (void*)(i + 1)); | |
} | |
void* threadres = NULL; | |
for (i = 0; i < N; ++i) { | |
pthread_join(customer_threads[i], &threadres); | |
} | |
free(table); | |
free(customer_threads); | |
sem_destroy(&waiting); | |
sem_destroy(&seat); | |
sem_destroy(&finish); | |
sem_destroy(&mutex); | |
sem_destroy(&lockseat); | |
return 0; | |
} | |
void* customer(void* cid) { | |
int id = (int)cid; | |
int seatnum = 0; | |
sem_wait(&mutex); | |
{ | |
int t = 0; | |
printf("%d customer entered, and %d customers are waiting...\n", id, waiting_num); | |
if (waiting_num == TN) { | |
printf("No available seat! Exit now!\n"); | |
sem_post(&mutex); | |
pthread_exit(NULL); | |
} | |
for (t = 0; t < TN; ++t) { | |
if (table[t] == 0) { | |
seatnum = t; | |
table[seatnum] = id; | |
break; | |
} | |
} | |
printf("%d customer sits at %d!\n", id, seatnum); | |
for (t = 0; t < TN; ++t) | |
printf("SEAT%d\t", t); | |
printf("BARBERSEAT\n"); | |
for (t = 0; t < TN; ++t) | |
printf("%d\t", table[t]); | |
printf("%d\n", barber_table); | |
++waiting_num; | |
} | |
sem_post(&mutex); | |
sem_post(&waiting); | |
sem_wait(&seat); | |
sem_wait(&mutex); | |
{ | |
table[seatnum] = 0; | |
barber_table = id; | |
--waiting_num; | |
} | |
sem_post(&mutex); | |
sem_post(&lockseat); | |
sem_wait(&finish); | |
sem_wait(&mutex); | |
{ | |
printf("Customer %d has just had his hair cut!\n", id); | |
barber_table = 0; | |
} | |
sem_post(&mutex); | |
sem_post(&leave); | |
pthread_exit(NULL); | |
} | |
void* barber(void* bid) { | |
while (1) { | |
if (waiting_num == 0) | |
printf("Barber is sleeping...\n"); | |
sem_wait(&waiting); | |
printf("Barber starts working...\n"); | |
sem_post(&seat); | |
sem_wait(&lockseat); | |
sleep(rand() % MAX_BTIME); | |
sem_post(&finish); | |
sem_wait(&leave); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment