编写的代码将管理任意数量的理发师而无需任何额外的信号量.只需为商店中的每位理发师开设一个Barber {}帖子.
维基百科评论中提到的问题是这样的:只是因为你在“理发师正在削减头发”状态中有M个理发师而且“客户正在剪头发”状态下的M个顾客,所以不能保证一些理发师不会尝试夹住一个以上的顾客,或者某个顾客头发上没有几个理发师.
换句话说,一旦允许适当数量的客户进入裁剪房,理发师和客户如何配对?你不能再说“理发师剪头发”和“顾客剪头发”;你必须说“理发师正在切割顾客C的头发”和“顾客正在用理发师B剪头发”.
// Assumptions about the meaning of 'haircut':
// each thread has a unique PID
// each thread can get its own PID via system.info.PID
// a barber uses a customer's PID to cut that custmer's hair
// a customer uses a barber's PID to get his hair cut by that barber
// Assumptions about the operating environment:
// a semaphore releases threads in the order that they were queued
Semaphore Customers = 0;
Semaphore Barbers = 0;
Mutex AccessSeats = 1;
int NumberOfFreeSeats = N;
int SeatPocket[N]; // (or 'PID SeatPocket[N];' if PID is a data type)
int SitHereNext = 0;
int ServeMeNext = 0;
// main program must start a copy of this thread for each barber in the shop
Barber {
int mynext, C;
while(1) {
sem_wait(Barbers); // join queue of sleeping barbers
sem_wait(AccessSeats); // mutex to protect seat changes
ServeMeNext = (ServeMeNext++) mod N; // select next customer
mynext = ServeMeNext;
C = SeatPocket[mynext]; // get selected customer's PID
SeatPocket[mynext] = system.info.PID; // leave own PID for customer
sem_post(AccessSeats); // release the seat change mutex
sem_post(Customers); // wake up selected customer
//
// barber is cutting hair of customer 'C'
//
}
}
// main program must start a copy of this thread at random intervals
// to represent the arrival of a continual stream of customers
Customer {
int myseat, B;
sem_wait(AccessSeats); // mutex to protect seat changes
if(NumberOfFreeSeats > 0) {
NumberOfFreeSeats--; // sit down in one of the seats
SitHereNext = (SitHereNext++) mod N;
myseat = SitHereNext;
SeatPocket[myseat] = system.info.PID;
sem_post(AccessSeats); // release the seat change mutex
sem_post(Barbers); // wake up one barber
sem_wait(Customers); // join queue of sleeping customers
sem_wait(AccessSeats); // mutex to protect seat changes
B = SeatPocket[myseat]; // barber replaced my PID with his own
NumberOfFreeSeats++; // stand up
sem_post(AccessSeats); // release the seat change mutex
//
// customer is having hair cut by barber 'B'
//
} else {
sem_post(AccessSeats); // release the seat change mutex
// customer leaves without haircut
}
system.thread.exit; // (or signal main program to kill this thread)
}