#include #include #include #include std::mutex cout_mutex; struct Fork { unsigned id; std::mutex mutex; }; class Philosopher { public: Philosopher(unsigned int id_, Fork& left_fork_, Fork& right_fork_) : id(id_), left_fork(left_fork_), right_fork(right_fork_) { } void operator()() { for (int i = 0; i < 5; ++i) { print_status("sits down at the table"); /* which fork has to be taken first? */ std::mutex* first; std::mutex* second; std::string first_text; std::string second_text; if (left_fork.id < right_fork.id) { first = &left_fork.mutex; second = &right_fork.mutex; first_text = "left"; second_text = "right"; } else { first = &right_fork.mutex; second = &left_fork.mutex; first_text = "right"; second_text = "left"; } { std::lock_guard lock1(*first); print_status("picks up the " + first_text + " fork"); { std::lock_guard lock2(*second); print_status("picks up the " + second_text + " fork"); { print_status("is dining"); } } print_status("returns the " + second_text + " fork"); } print_status("returns the " + first_text + " fork"); print_status("leaves the table"); } } private: void print_status(const std::string& msg) const { std::lock_guard lock(cout_mutex); std::cout << "philosopher [" << id << "]: " << msg << std::endl; } unsigned int id; Fork& left_fork; Fork& right_fork; }; int main() { constexpr unsigned int PHILOSOPHERS = 5; std::thread philosopher[PHILOSOPHERS]; Fork fork[PHILOSOPHERS]; for (int i = 0; i < PHILOSOPHERS; ++i) { fork[i].id = i; } for (int i = 0; i < PHILOSOPHERS; ++i) { philosopher[i] = std::thread(Philosopher(i+1, fork[i], fork[(i + PHILOSOPHERS - 1) % PHILOSOPHERS])); } for (int i = 0; i < PHILOSOPHERS; ++i) { philosopher[i].join(); } }