100 lines
2.6 KiB
C++
100 lines
2.6 KiB
C++
#include <philosopher.hpp>
|
|
|
|
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<std::mutex> 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<std::mutex> lk{changingForkState};
|
|
setState(PhilosopherState::HUNGRY);
|
|
{
|
|
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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();
|
|
}
|
|
}
|
|
|