Created
May 16, 2021 12:02
-
-
Save Tokubara/60a3c4b784e70ec00110df8e9bd93ce3 to your computer and use it in GitHub Desktop.
理发师问题的信号量实现
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 <pthread.h> | |
#include <semaphore.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#define CHAIR_NUM 3 | |
#define SOFA_NUM 4 | |
#define CAPACITY 20 | |
#define CUSTOMER_NUM 20 | |
#define thread_sum (1 + CHAIR_NUM + CUSTOMER_NUM) | |
#define customer_say(sentence) printf("%d:" sentence "\n", id); | |
#define true 1 | |
sem_t capacity, sofa, chair, coord, have_customer, cut_finish, payment, receipt; | |
void* customer(void* arg) { | |
int id = *((int*)arg)-(1 + CHAIR_NUM); | |
customer_say("I want to enter"); | |
sem_wait(&capacity); | |
customer_say("I enter, now I want a sofa"); | |
sem_wait(&sofa); | |
customer_say("I get sofa, now I want a chair"); | |
sem_wait(&chair); | |
sem_post(&sofa); | |
customer_say("I get a chair, I want haircut"); | |
sem_post(&have_customer); | |
sem_wait(&cut_finish); | |
customer_say("I get haircut, now I want to pay"); | |
sem_post(&chair); | |
sem_post(&payment); | |
sem_wait(&receipt); | |
customer_say("pay finish, I can leave now"); | |
sem_post(&capacity); | |
customer_say("done"); | |
} | |
void* barber(void* arg) { | |
while(true) { | |
sem_wait(&have_customer); | |
sem_wait(&coord); | |
puts("I'm working on haircut"); | |
sleep(0.5); | |
sem_post(&cut_finish); | |
sem_post(&coord); | |
} | |
} | |
void* cashier(void* arg) { | |
while(true) { | |
sem_wait(&payment); | |
sem_wait(&coord); | |
sleep(0.1); | |
puts("payment finish"); | |
sem_post(&receipt); | |
sem_post(&coord); | |
} | |
} | |
int main() | |
{ | |
sem_init(&capacity, 0, CAPACITY); | |
sem_init(&sofa, 0, SOFA_NUM); | |
sem_init(&chair, 0, CHAIR_NUM); | |
sem_init(&coord, 0, CHAIR_NUM); | |
sem_init(&have_customer, 0, 0); | |
sem_init(&cut_finish, 0, 0); | |
sem_init(&payment, 0, 0); | |
sem_init(&receipt, 0, 0); | |
pthread_t pthread_all[thread_sum]; | |
pthread_create(&pthread_all[0], NULL, cashier, NULL); | |
int end = CHAIR_NUM + 1; | |
for (int i = 1; i < end; i++) { | |
pthread_create(&pthread_all[i], NULL, barber, NULL); | |
} | |
end = 1 + CHAIR_NUM + CUSTOMER_NUM; | |
for (int i = 1 + CHAIR_NUM; i < end; i++) { | |
pthread_create(&pthread_all[i], NULL, customer, (void*)&i); | |
} | |
for (int i = 1 + CHAIR_NUM; i < end; i++) { | |
pthread_join(pthread_all[i], NULL); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment