#include std::mutex changingForkState; std::mutex printing; void Philosopher::setState(PhilosopherState state) { this->state = state; } size_t Philosopher::leftPhilosopherNumber(void) { return (numberOfPhilosopher - 1 + philosophers->size()) % philosophers->size(); } size_t Philosopher::rightPhilosopherNumber(void) { return (numberOfPhilosopher + 1) % philosophers->size(); } PhilosopherPtr Philosopher::leftPhilosopher(void) { return (*philosophers)[leftPhilosopherNumber()]; } PhilosopherPtr Philosopher::rightPhilosopher(void) { return (*philosophers)[rightPhilosopherNumber()]; } void Philosopher::think() { size_t duration = random(100, 1000); { std::lock_guard lk{printing}; std::cout << "Philosopher " << numberOfPhilosopher << " is thinking for " << duration << "." << std::endl; } std::this_thread::sleep_for(std::chrono::milliseconds(duration)); } void Philosopher::takeForks() { { std::lock_guard lk{changingForkState}; setState(PhilosopherState::HUNGRY); { std::lock_guard lk{printing}; std::cout << "Philosopher " << numberOfPhilosopher << " is hungry." << std::endl; } test(); } hasBothForks.acquire(); } void Philosopher::eat() { size_t duration = random(100, 1000); { std::lock_guard lk{printing}; std::cout << "Philosopher " << numberOfPhilosopher << " is eating." << std::endl; } std::this_thread::sleep_for(std::chrono::milliseconds(duration)); } void Philosopher::putForks() { std::lock_guard lk{changingForkState}; state = PhilosopherState::THINKING; leftPhilosopher()->test(); rightPhilosopher()->test(); } PhilosopherState Philosopher::getState() { return state; } Philosopher::Philosopher(ListOfPhilosophersPtr philosophers, int numberOfPhilosopher): state(PhilosopherState::THINKING) { this->numberOfPhilosopher = numberOfPhilosopher; this->philosophers = philosophers; } void Philosopher::startThread() { { std::lock_guard lk{printing}; std::cout << "Philosopher " << numberOfPhilosopher << " has sit in the table." << std::endl; } while (true) { think(); takeForks(); eat(); putForks(); } } void Philosopher::test() { if (state == PhilosopherState::HUNGRY && leftPhilosopher()->getState() != PhilosopherState::EATING && rightPhilosopher()->getState() != PhilosopherState::EATING) { setState(PhilosopherState::EATING); hasBothForks.release(); } }