Skip to content

Instantly share code, notes, and snippets.

@mengcz13
Created May 6, 2017 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mengcz13/c032ef918cf8ceb34761cc207c9a80ed to your computer and use it in GitHub Desktop.
Save mengcz13/c032ef918cf8ceb34761cc207c9a80ed to your computer and use it in GitHub Desktop.
Solution for barber problem~
#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