Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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;
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote