I'm trying to solve the following problem: " The analogy is based upon a hypothetical barber shop with one barber. The barber has one barber's chair in a cutting room and a waiting room containing a number of chairs in it. When the barber finishes cutting a customer's hair, he dismisses the customer and goes to the waiting room to see if there are others waiting. If there are, he brings one of them back to the chair and cuts their hair. If there are none, he returns to the chair and sleeps in it.
Each customer, when they arrive, looks to see what the barber is doing. If the barber is sleeping, the customer wakes him up and sits in the cutting room chair. If the barber is cutting hair, the customer stays in the waiting room. If there is a free chair in the waiting room, the customer sits in it and waits their turn. If there is no free chair, the customer leaves. "
My entire code is the following:
// Example program
#include <iostream>
#include <string>
#include <mutex>
#include <thread>
#include <chrono>
#include <atomic>
#include <deque>
#include <vector>
#include <condition_variable>
using namespace std;
const unsigned int NUM_CHAIRS = 2;
const unsigned int NUM_CUSTOMERS = 1;
// In a barbershop, customers are coming in and there is only one barber. If the barber is cutting a
// customers hair, the customer will wait. There are only a limited amount of chairs for the customer
// to wait on. If the chairs are full, then the customer will leave and try again later.
struct Barbershop
{
public:
Barbershop(): num_waiting(0){};
condition_variable cv; // Acts like a receptionist
atomic<int> num_waiting; // Number of customers waiting on chairs
mutex cout_mtx;
};
class Barber
{
public:
Barber(Barbershop& shop): mem_shop(shop), hislife(&Barber::work, this){};
void work()
{
unique_lock<mutex> lk(b_mu);
if(mem_shop.num_waiting == 0)
{
mem_shop.cout_mtx.lock();
cout << "Barber sleeping...\n";
mem_shop.cout_mtx.unlock();
}
mem_shop.cv.wait(lk, [this]{return mem_shop.num_waiting > 0;}); // []{return mem_shop.num_waiting}
mem_shop.cout_mtx.lock();
cout << "Time to cut some hair!\n";
mem_shop.cout_mtx.unlock();
lk.unlock();
mem_shop.cv.notify_one();
this_thread::sleep_for(chrono::milliseconds(100));
mem_shop.num_waiting--;
};
~Barber()
{
hislife.join();
}
int jn;
mutex b_mu;
Barbershop& mem_shop;
thread hislife;
};
class Customer
{
public:
Customer(Barbershop& shop, int name_id): mem_shop(shop), name(name_id), hislife(&Customer::tryGetHaircut, this){};
void tryGetHaircut()
{
if(mem_shop.num_waiting == NUM_CHAIRS)
{
mem_shop.cout_mtx.lock();
cout << name <<"'s wait was too long. Leaving!\n";
mem_shop.cout_mtx.unlock();
}
else
{
mem_shop.num_waiting++;
std::unique_lock<mutex> lk(c_mu);
mem_shop.cv.wait(lk);
mem_shop.cout_mtx.lock();
cout << name << " is getting haircut!\n";
mem_shop.cout_mtx.unlock();
}
};
~Customer()
{
hislife.join();
}
mutex c_mu;
Barbershop& mem_shop;
thread hislife;
unsigned int name;
};
int main()
{
Barbershop mybarbershop;
Barber dan();
vector<Customer*> customers;
customers.reserve(NUM_CUSTOMERS-1);
for(unsigned int i=0; i<NUM_CUSTOMERS; i++)
{
customers.push_back(new Customer(mybarbershop, i+1));
}
for(auto s : customers)
{
delete s;
}
cout << "Program Finished!\n";
return 0;
}
However, my code isn't even making it into the Barbers thread and seems to get locked on the condition variables. Are there any blatant issues I've made in logic/syntax in solving this problem?
I am still a beginner so any help on the topic would be greatly appreciated.