Compare commits
10 Commits
12fe9a21d5
...
4ae503d4f9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ae503d4f9 | ||
|
|
a60331d0be | ||
|
|
b31b9f83ea | ||
|
|
6aaaba3eb9 | ||
|
|
fad41c80b3 | ||
|
|
bb3dc32a97 | ||
|
|
234c2bab0b | ||
| f1b6435b7e | |||
|
|
c920829d3b | ||
|
|
e187751e5a |
11
README.md
11
README.md
@ -13,6 +13,17 @@ 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
|
||||
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
|
||||
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,70 +12,81 @@ mutex cout_mutex;
|
||||
#define N 25
|
||||
|
||||
// GLOBAL VARIABLES
|
||||
counting_semaphore free_chairs(N);
|
||||
binary_semaphore barber_free(1);
|
||||
binary_semaphore barber_sem(1);
|
||||
int carsWaiting = 0;
|
||||
mutex mutexCar;
|
||||
binary_semaphore carArrived(0);
|
||||
binary_semaphore bayFree(0);
|
||||
binary_semaphore carWashed(0);
|
||||
binary_semaphore washingDone(0);
|
||||
|
||||
void get_haircut(size_t id)
|
||||
void car(size_t id)
|
||||
{
|
||||
this_thread::sleep_for(chrono::seconds(10));
|
||||
print("Client " << id << " got a haircut");
|
||||
// car arrives
|
||||
print("Car " << id << " arrives at the car wash");
|
||||
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 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()
|
||||
void attendant()
|
||||
{
|
||||
while (true) {
|
||||
print("Barber is sleeping");
|
||||
barber_sem.acquire();
|
||||
print("Barber woke up");
|
||||
cutHair();
|
||||
barber_free.release();
|
||||
// rendezvous 1
|
||||
carArrived.acquire(); // wait X
|
||||
bayFree.release(); // signal Y
|
||||
|
||||
// washCar
|
||||
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()
|
||||
{
|
||||
barber_sem.acquire();
|
||||
thread barber_thread(barber);
|
||||
print("Client will arrive");
|
||||
vector<thread> clients {};
|
||||
print("Car wash opening with " << N << " waiting spaces");
|
||||
|
||||
thread attendantThread(attendant);
|
||||
attendantThread.detach();
|
||||
|
||||
vector<thread> cars {};
|
||||
for(size_t i = 0; i < N+1; ++i)
|
||||
{
|
||||
thread t(client, i);
|
||||
clients.push_back(std::move(t));
|
||||
thread t(car, i);
|
||||
cars.push_back(std::move(t));
|
||||
}
|
||||
|
||||
barber_thread.join();
|
||||
for (auto &client: clients) {
|
||||
client.join();
|
||||
for (auto &car: cars) {
|
||||
car.join();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user