Solutions to high-frequency interview questions of LeetCode in C++17, taking into account both efficiency and comprehensibility.
class DiningPhilosophers {
public:
DiningPhilosophers() {}
void wantsToEat(int philosopher, function<void()> pickLeftFork,
function<void()> pickRightFork, function<void()> eat,
function<void()> putLeftFork, function<void()> putRightFork) {
m.lock();
pickLeftFork();
pickRightFork();
eat();
putLeftFork();
putRightFork();
m.unlock();
}
private:
mutex m;
};
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; // 右侧叉子编号
mt.lock(); // 保证一个哲学家能同时拿到两个叉子
lock_guard<mutex> lk1{m[l]};
lock_guard<mutex> lk2{m[r]};
pickLeftFork();
pickRightFork();
mt.unlock(); // 已同时拿到两个叉子,解锁全局锁
eat();
putLeftFork();
putRightFork();
} // 进餐结束解锁叉子
private:
mutex mt; // 全局锁
mutex m[5]; // 每个叉子一把锁
};
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;
lock(m[l], m[r]);
lock_guard<mutex> lk1{m[l], adopt_lock};
lock_guard<mutex> lk2{m[r], adopt_lock};
pickLeftFork();
pickRightFork();
eat();
putLeftFork();
putRightFork();
}
private:
mutex m[5];
};
class DiningPhilosophers {
public:
DiningPhilosophers() {}
void wantsToEat(int philosopher, function<void()> pickLeftFork,
function<void()> pickRightFork, function<void()> eat,
function<void()> putLeftFork, function<void()> putRightFork) {
scoped_lock lk{m[philosopher], m[(philosopher + 1) % 5]};
pickLeftFork();
pickRightFork();
eat();
putLeftFork();
putRightFork();
}
private:
mutex m[5];
};