思路:
参考题解:https://leetcode-cn.com/problems/the-dining-philosophers/solution/zhe-xue-jia-jiu-can-wen-ti-by-mike-meng/
解法1:控制同时拿筷子的哲学家人数(不多于4个)
class Semaphore {
public:
Semaphore(int count = 0): count_(count){}
void Set(int count) {
count_ = count;
}
void Signal() {
unique_lock<mutex>lock(mutex_);
++count_;
cv_.notify_one();
}
void Wait() {
unique_lock<mutex>lock(mutex_);
while(count_ <= 0) {
cv_.wait(lock);
}
--count_;
}
private:
mutex mutex_;
condition_variable cv_;
int count_;
};
class DiningPhilosophers {
public:
DiningPhilosophers() {
guid.Set(4);
}
void wantsToEat(int philosopher,
function<void()> pickLeftFork,
function<void()> pickRightFork,
function<void()> eat,
function<void()> putLeftFork,
function<void()> putRightFork) {
int l = philosopher;
int r = (philosopher + 1) % 5;
guid.Wait();
lock[l].lock();
lock[r].lock();
pickLeftFork();
pickRightFork();
eat();
putRightFork();
putLeftFork();
lock[r].unlock();
lock[l].unlock();
guid.Signal();
}
private:
mutex lock[5];
Semaphore guid;
};
解法2:使用互斥量,使得哲学家一次只能拿上左右筷子
class DiningPhilosophers {
public:
DiningPhilosophers() {
}
void wantsToEat(int philosopher,
function<void()> pickLeftFork,
function<void()> pickRightFork,
function<void()> eat,
function<void()> putLeftFork,
function<void()> putRightFork) {
int l = philosopher;
int r = (philosopher + 1) % 5;
guid.lock();
lock[l].lock();
lock[r].lock();
pickLeftFork();
pickRightFork();
guid.unlock();
eat();
putRightFork();
putLeftFork();
lock[r].unlock();
lock[l].unlock();
}
private:
mutex lock[5];
mutex guid;
};
解法3:限定就餐,奇数位优先拿左边筷子,偶数位优先拿右边筷子
class DiningPhilosophers {
public:
DiningPhilosophers() {
}
void wantsToEat(int philosopher,
function<void()> pickLeftFork,
function<void()> pickRightFork,
function<void()> eat,
function<void()> putLeftFork,
function<void()> putRightFork) {
int l = philosopher;
int r = (philosopher + 1) % 5;
if(philosopher % 2 == 0) {
lock[r].lock();
lock[l].lock();
pickRightFork();
pickLeftFork();
eat();
putLeftFork();
putRightFork();
lock[l].unlock();
lock[r].unlock();
} else {
lock[l].lock();
lock[r].lock();
pickLeftFork();
pickRightFork();
eat();
putRightFork();
putLeftFork();
lock[r].unlock();
lock[l].unlock();
}
}
private:
mutex lock[5];
};