Dining Philosophers C++: Create a Cygwin or Unix console program that implements
ID: 669340 • Letter: D
Question
Dining Philosophers
C++: Create a Cygwin or Unix console program that implements a solution to the Dining Philosopher problem. Use threads and semaphores in the pthread and semaphore libraries to implement the solution below.
Create five threads to represent the philosophers using the philosopher() function as the thread entry point. You will need to add a main() function that creates the threads.
Use printf() statements to show what is happening to each philosopher (thinking or eating.
NOTE: You solution must be based on the code below:
Explanation / Answer
working c++ code
#include <iostream>
#include <vector>
#include <thread>
#include <random>
#include <condition_variable>
namespace {
int sleep_for_random_time() {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> dist(1000, 4000);
return dist(mt);
}
}
class DiningPhilosopher {
public:
DiningPhilosopher(int numOfPhilosophers_ = 5, int numOfForks_ = 5, int numOfEating_ = 3) : numOfPhilosophers(numOfPhilosophers_), numOfForks(numOfForks_), numOfEating(numOfEating_) {
forks.push_back(new Fork);
forks.push_back(new Fork);
forks.push_back(new Fork);
forks.push_back(new Fork);
forks.push_back(new Fork);
numAllowed = numOfForks - 1;
}
~DiningPhilosopher() {
for(const auto& fork : forks) {
delete fork;
}
}
DiningPhilosopher(const DiningPhilosopher&) = delete;
DiningPhilosopher& operator = (const DiningPhilosopher&) = delete;
void StartDining() {
for(int i = 0; i < numOfPhilosophers; ++i) {
threads.push_back(std::thread(&DiningPhilosopher::Philosopher, this, i));
}
std::for_each(threads.begin(),threads.end(), std::mem_fn(&std::thread::join));
}
private:
void WaitForPermission() {
std::lock_guard<std::mutex> lock(permission);
cv.wait(permission, [this] { return numAllowed > 0; });
--numAllowed;
}
void GrantPermission() {
std::lock_guard<std::mutex> lock(permission);
++numAllowed;
if(numAllowed == 1) {
cv.notify_all();
}
}
void Think(int id) {
std::chrono::milliseconds duration(sleep_for_random_time());
std::this_thread::sleep_for(duration);
}
void Eat(int id) {
this->WaitForPermission();
forks[id]->mux.lock();
forks[(id + 1) % numOfForks]->mux.lock();
std::cout << "Philosopher "<< id << " is eating" << std::endl;
this->Think(id);
std::cout << "Philosopher "<< id << " has finished eating" << std::endl;
forks[id]->mux.unlock();
forks[(id + 1) % numOfForks]->mux.unlock();
this->GrantPermission();
}
void Philosopher(int id) {
for(int i = 0; i < numOfEating; ++i) {
this->Think(id);
this->Eat(id);
}
std::cout << "Philosopher " << id << " DONE" << std::endl;
}
struct Fork {
std::mutex mux;
};
int numOfEating;
int numOfPhilosophers;
int numAllowed;
int numOfForks;
std::vector<std::thread> threads;
std::vector<Fork*> forks;
std::mutex permission;
std::condition_variable_any cv;
};
int main()
{
DiningPhilosopher dp;
dp.StartDining();
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.