LeetCode 1226. 哲学家进餐(C++多线程)

在这里插入图片描述

思路:
参考题解: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];
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值