Compare commits
No commits in common. "4ae503d4f9f9b57305fe2e7afd24002524f8fa85" and "12fe9a21d5114f38bff2531cba91b18479082455" have entirely different histories.
4ae503d4f9
...
12fe9a21d5
11
README.md
11
README.md
@ -13,17 +13,6 @@ customer sits in one of the free chairs. If the barber is asleep, the
|
|||||||
customer wakes up the barber. Write a program to coordinate the
|
customer wakes up the barber. Write a program to coordinate the
|
||||||
barber and the customers.
|
barber and the customers.
|
||||||
|
|
||||||
## Similar implementation
|
|
||||||
We implemented the following problem, which is similar to the barbershop problem
|
|
||||||
### Car Wash Problem
|
|
||||||
Imagine a car wash service with the following constraints:
|
|
||||||
|
|
||||||
* **One Car Wash Bay**: There's only one car wash bay where cars are washed. If the bay is empty, a car can directly go into the bay for a wash. If the bay is occupied, the car has to wait.
|
|
||||||
|
|
||||||
* **Waiting Area:** There's a waiting area that can accommodate *n* cars. When the bay is occupied, arriving cars will park in the waiting area. If the waiting area is full, the car has to come back later.
|
|
||||||
|
|
||||||
* **Attendant**: An attendant is responsible for signaling cars to move into the bay when it's free. If there are no cars in the waiting area and the bay is free, the attendant can take a break.
|
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
The purpose of this project is to implement a semaphore from the [little book of semaphores](https://greenteapress.com/semaphores/LittleBookOfSemaphores.pdf) for the school subject R.5.A.10.
|
The purpose of this project is to implement a semaphore from the [little book of semaphores](https://greenteapress.com/semaphores/LittleBookOfSemaphores.pdf) for the school subject R.5.A.10.
|
||||||
|
|
||||||
|
|||||||
107
main.cpp
107
main.cpp
@ -12,81 +12,70 @@ mutex cout_mutex;
|
|||||||
#define N 25
|
#define N 25
|
||||||
|
|
||||||
// GLOBAL VARIABLES
|
// GLOBAL VARIABLES
|
||||||
int carsWaiting = 0;
|
counting_semaphore free_chairs(N);
|
||||||
mutex mutexCar;
|
binary_semaphore barber_free(1);
|
||||||
binary_semaphore carArrived(0);
|
binary_semaphore barber_sem(1);
|
||||||
binary_semaphore bayFree(0);
|
|
||||||
binary_semaphore carWashed(0);
|
|
||||||
binary_semaphore washingDone(0);
|
|
||||||
|
|
||||||
void car(size_t id)
|
void get_haircut(size_t id)
|
||||||
{
|
{
|
||||||
// car arrives
|
this_thread::sleep_for(chrono::seconds(10));
|
||||||
print("Car " << id << " arrives at the car wash");
|
print("Client " << id << " got a haircut");
|
||||||
mutexCar.lock();
|
|
||||||
if (carsWaiting == N) {
|
|
||||||
mutexCar.unlock();
|
|
||||||
print("Car " << id << " leaves due to no waiting space");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
++carsWaiting;
|
|
||||||
mutexCar.unlock();
|
|
||||||
|
|
||||||
// rendezvous 1
|
|
||||||
carArrived.release(); // signal X
|
|
||||||
bayFree.acquire(); // wait Y
|
|
||||||
|
|
||||||
// getCarWash
|
|
||||||
print("Car " << id << " is being washed");
|
|
||||||
this_thread::sleep_for(chrono::seconds(1));
|
|
||||||
print("Car " << id << " is washed");
|
|
||||||
|
|
||||||
// rendezvous 2
|
|
||||||
carWashed.release(); // signal X'
|
|
||||||
washingDone.acquire(); // wait Y'
|
|
||||||
|
|
||||||
// car leaves
|
|
||||||
mutexCar.lock();
|
|
||||||
--carsWaiting;
|
|
||||||
mutexCar.unlock();
|
|
||||||
print("Car " << id << " leaves the car wash");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void attendant()
|
void cutHair()
|
||||||
|
{
|
||||||
|
this_thread::sleep_for(chrono::seconds(10));
|
||||||
|
print("Barber cut hair");
|
||||||
|
}
|
||||||
|
|
||||||
|
void client(size_t id)
|
||||||
|
{
|
||||||
|
print("Client " << id << " arrived");
|
||||||
|
bool isAChairFree = free_chairs.try_acquire();
|
||||||
|
if (!isAChairFree){
|
||||||
|
print("no chairs available");
|
||||||
|
print("Client " << id << " left");
|
||||||
|
return; //Bye bye
|
||||||
|
}
|
||||||
|
|
||||||
|
//wait for barber
|
||||||
|
barber_free.acquire();
|
||||||
|
print("Client " << id << " woke the barber up");
|
||||||
|
barber_sem.release();
|
||||||
|
// Get a haircut
|
||||||
|
get_haircut(id);
|
||||||
|
// Bye bye;
|
||||||
|
free_chairs.release();
|
||||||
|
print("Client " << id << " left");
|
||||||
|
}
|
||||||
|
|
||||||
|
void barber()
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
// rendezvous 1
|
print("Barber is sleeping");
|
||||||
carArrived.acquire(); // wait X
|
barber_sem.acquire();
|
||||||
bayFree.release(); // signal Y
|
print("Barber woke up");
|
||||||
|
cutHair();
|
||||||
// washCar
|
barber_free.release();
|
||||||
print("Attendant starts washing a car");
|
|
||||||
this_thread::sleep_for(chrono::seconds(1));
|
|
||||||
print("Attendant finishes washing");
|
|
||||||
|
|
||||||
// rendezvous 2
|
|
||||||
carWashed.acquire(); // wait X'
|
|
||||||
washingDone.release(); // signal Y'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
print("Car wash opening with " << N << " waiting spaces");
|
barber_sem.acquire();
|
||||||
|
thread barber_thread(barber);
|
||||||
thread attendantThread(attendant);
|
print("Client will arrive");
|
||||||
attendantThread.detach();
|
vector<thread> clients {};
|
||||||
|
|
||||||
vector<thread> cars {};
|
|
||||||
for(size_t i = 0; i < N+1; ++i)
|
for(size_t i = 0; i < N+1; ++i)
|
||||||
{
|
{
|
||||||
thread t(car, i);
|
thread t(client, i);
|
||||||
cars.push_back(std::move(t));
|
clients.push_back(std::move(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &car: cars) {
|
barber_thread.join();
|
||||||
car.join();
|
for (auto &client: clients) {
|
||||||
|
client.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user