Fix to something that I've seen a few people miss
A lot of posts I looked at use (philosopher + 1) % 5 or something like that, which does not work for for acquisition. Basically, there is nothing stopping every
A lot of posts I looked at use (philosopher + 1) % 5 or something like that, which does not work for for acquisition. Basically, there is nothing stopping every philosopher acquiring the fork that corresponds to their id, so that no progress can be made. In order to solve this, it is necessary to ensure that mutexes are always acquired in the same global order. Also, as a side note, the trivial solution with a single mutex does not scale well to many philosophers, where it is possible to have highly parallel eating.\n\nAnyway, code:\n\n```\nclass DiningPhilosophers {\npublic:\n    mutex mutex_list[5] = {mutex(), mutex(), mutex(), mutex(), mutex()};\n    DiningPhilosophers() {\n        \n    }\n\n    void wantsToEat(int philosopher,\n                    function<void()> pickLeftFork,\n                    function<void()> pickRightFork,\n                    function<void()> eat,\n                    function<void()> putLeftFork,\n                    function<void()> putRightFork) {\n        reserve_both_forks(philosopher);\n        pickLeftFork();\n        pickRightFork();\n        eat();\n        putLeftFork();\n        putRightFork();\n        release_both_forks(philosopher);\n\t\t\n    }\n    \n    void reserve_both_forks(int id) {\n        if (id <= 3) {\n            mutex_list[id].lock();\n            mutex_list[id + 1].lock();\n        } else {\n            mutex_list[0].lock();  # Edit: this is the crucial part, so that the fork with the lower id is always reserved first\n            mutex_list[4].lock();\n        }\n    }\n    void release_both_forks(int id) {\n        mutex_list[id].unlock();\n        mutex_list[(id + 1) % 5].unlock();\n    }\n};\n```\n\n
[]