精华内容
下载资源
问答
  • 哲学家进餐问题 C++实现

    千次阅读 2019-02-26 19:28:34
    哲学家进餐问题描述 假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉...

    哲学家进餐问题描述

    假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。

    三个求解策略

    首先肯定是使用线程来模拟哲学家的,一个线程是一个哲学家,然后要求线程在进行资源竞争时不死锁。

    下面给出几种求解策略

    1. 利用锁机制,每次保证一个哲学家在吃,哲学家想吃的时候,先测试一下锁,如果能获得锁,则测试一下自己的筷子以及右边的筷子能不能拿,如果能拿则拿起筷子吃,否则阻塞,哲学家思考时测试一下能不能获得互斥锁,如果能则该哲学家放下自己的筷子和右边的筷子。

    2. 封装信号量,定义类Semaphore代表信号量,并封装down和up方法,当信号量执行down方法时信号量减一,如果值变为0则阻塞线程,调用up方法使信号量加一,然后定义信号量metux=4来保证同时只有四个哲学家拿筷子,信号量筷子chopsticks []={1,1,1,1,1,…,1},首先metux.down(),保证最多进4个哲学家,然后down自己的筷子,down右边的筷子,如果线程未阻塞,则可以吃饭,吃完后,up右筷子,up自己的筷子,最后metux.up()。

    3. 利用封装好的信号量,使用奇偶法。防止哲学家饿死的情况,制定如下规则:

    规则: 奇数号的哲学家先拿起右边的筷子再拿起左边的筷子。

                偶数号哲学家先拿起左边的筷子,再拿起右边的筷子。

                如果哲学家抢到一只筷子,在抢占另一只筷子时失败,则要放弃已经抢占到的资源。

                左右两边都抢到筷子的哲学家,吃完放后释放资源。

    实现时只需在求解策略二的基础上加个奇偶判断就可以了

    C++实现 (JAVA实现的话到处都有)

    C++11的thread线程类: C++11引入的跨平台的线程类

    C++11 mutex互斥锁:mutex:独占的互斥量

    condition_variable条件变量: 条件变量是C++11提供的另外一种用于等待的同步机制,它能阻塞一个或多个线程,直到收到另外一个线程发出的通知或者超时,才会唤醒当前阻塞的线程

    代码如下

    #include<iostream>
    #include<thread>
    #include<mutex>
    #include<windows.h>
    #include<chrono>
    #include<condition_variable>
    #include<map>
    #include<functional>
    #include<string>
    #include<sstream>
    #include<vector>
    #include<functional>
    #include<ctime>
    #include<cstdlib>
    #define random(a,b) (rand()%(b-a+1)+a)
    using namespace std;
    unsigned int MaxN;
    namespace Method {
    mutex alock;
    condition_variable t;
    class Semaphore{//信号量的封装 down up操作
    private:
        unsigned int m;
    public:
        Semaphore(unsigned int x):m(x){}
        Semaphore(){}
        Semaphore(const Semaphore& t){m = t.m;}
        ~Semaphore(){}
        void down(){
          unique_lock<mutex> locker(alock);
           while(m==0){
               cout<<"(thread id="<<this_thread::get_id()<<" is wait)"<<endl;
               t.wait(locker);
           }
            m--;
        }
        void up(){
            alock.lock();
            m++;
            t.notify_all();
            alock.unlock();
        }
        bool operator == (const Semaphore &t) {
            return m == t.m;
        }
        bool operator !=(const Semaphore &t){
            return m!=t.m;
        }
        bool operator == (const unsigned int &t) {
            return m == t;
        }
        bool operator != (const unsigned int &t){
            return m!=t;
        }
        void operator = (const Semaphore &t){
            m = t.m;
        }
        void operator = (const unsigned int &t){
            m = t;
        }
        Semaphore operator + (const Semaphore &t){
            return Semaphore(m+t.m);
        }
        Semaphore operator + (const unsigned int &t){
            return Semaphore(m+t);
        }
    };
    int Int(thread::id id){
      stringstream ss;
      ss<<id;
      return std::stoi(ss.str());
    }
    Semaphore mutexs = 4;
    Semaphore chopsticks[10000];
    //求解策略部分的代码是重点
    //求解策略一
    auto functionA = []()->void{ //lambda表达式
            auto eating = []()->void{ //获取线程ID
    
                   unique_lock<mutex> locker(alock);
                   int current_id = Int(this_thread::get_id())-2;
                   while(chopsticks[current_id]==0||chopsticks[(current_id+1)%MaxN]==0){ //是否能拿自己的筷子和右边的筷子,如果不能则阻塞
                       cout<<"(thread id="<<this_thread::get_id()<<" is wait)"<<endl;
                       t.wait(locker); //阻塞线程
                   }
                   chopsticks[current_id] = 0; //拿自己的筷子
                   chopsticks[(current_id+1)%MaxN] = 0; //拿右边的筷子
                   cout<<"Philosopher"<<current_id<<" are eating (thread id="<<this_thread::get_id()<<" is run)"<<endl;
    
              };
             auto thinking = []()->void{ //思考方法
                   alock.lock(); //获得锁
                   int current_id = Int(this_thread::get_id())-2; //当前线程
                   chopsticks[current_id]=1; //放下自己的筷子
                   chopsticks[(current_id+1)%MaxN]=1; //放下右边的筷子
                   t.notify_all(); //唤醒所有线程
                   cout<<"Philosopher"<<current_id<<" are thinking (thread id="<<this_thread::get_id()<<" is run)"<<endl;
                   alock.unlock(); //释放锁
               };
           while(true){ //无限执行线程
               thinking();
               chrono::milliseconds s(1000); //睡眠1s
               this_thread::sleep_for(s);
               eating();
           }
       };
    //求解策略二 
     auto functionB = []()->void{ //lambda表达式
     
                while(true){ //无限执行线程
                    mutexs.down(); //down(mutex)
                    size_t id = Int(this_thread::get_id())-2; //线程ID
                    chopsticks[id].down(); //down(chopsticks[id])
                    chopsticks[(id+1)%MaxN].down(); //down(chopsticks[(id+1)%MaxN])
                    alock.lock();  //锁一下,保证同时只有一个线程往屏幕里输出
                    cout<<"Philosopher"<<id<<" are eating (thread id="<<this_thread::get_id()<<" is run)"<<endl;
                    alock.unlock(); //释放锁
                    chrono::milliseconds s(1000); //睡眠1s
                    this_thread::sleep_for(s);
    
                    chopsticks[(id+1)%MaxN].up(); //up(chopsticks[(id+1)%MaxN])
                    chopsticks[id].up(); //up(chopsticks[id])
                    alock.lock(); //锁一下,保证同时只有一个线程往屏幕里输出
                    cout<<"Philosopher"<<id<<" are thinking (thread id="<<this_thread::get_id()<<" is run)"<<endl;
                    alock.unlock(); //释放锁
                    this_thread::sleep_for(s);
                    mutexs.up();
    
                }
    
    
    };
    //求解策略三
    auto functionC = []()->void{ //lambda表达式
    
                while(true){ //无限执行线程
                    int id = Int(this_thread::get_id())-2; //获取当前线程
                    if(id%2){
                        //奇数
                        chopsticks[(id+1)%MaxN].down(); //down(chopsticks[(id+1)%MaxN])
                        chopsticks[id].down(); //down(chopsticks[id])
                        alock.lock(); //锁一下,保证同时只有一个线程往屏幕里输出
                        cout<<"Philosopher"<<id<<" are eating (thread id="<<this_thread::get_id()<<" is run)"<<endl;
                        alock.unlock(); //释放锁
                        chrono::milliseconds s(1000); //睡眠1s
                        this_thread::sleep_for(s);
                        chopsticks[(id+1)%MaxN].up(); //up(chopsticks[(id+1)%MaxN])
                        chopsticks[id].up(); //up(chopsticks[id])
    
                    }else{
                        //偶数
                        chopsticks[id].down(); //down(chopsticks[id])
                        chopsticks[(id+1)%MaxN].down(); //down(chopsticks[(id+1)%MaxN])
                        alock.lock(); //锁一下,保证同时只有一个线程往屏幕里输出
                        cout<<"Philosopher"<<id<<" are eating (thread id="<<this_thread::get_id()<<" is run)"<<endl;
                        alock.unlock(); //释放锁
                        chrono::milliseconds s(1000); //睡眠1s
                        this_thread::sleep_for(s);
                        chopsticks[id].up(); //up(chopsticks[id])
                        chopsticks[(id+1)%MaxN].up(); //up(chopsticks[(id+1)%MaxN])
                    }
                   alock.lock(); //锁一下,保证同时只有一个线程往屏幕
                   cout<<"Philosopher"<<id<<" are thinking (thread id="<<this_thread::get_id()<<" is run)"<<endl;
                   alock.unlock(); //释放锁
    
                       }
                    };
    
    }
    using namespace Method;
    //定义哲学家类
    class Philosopher{
    private:
        vector<function<void()> > fns;
    
        Philosopher(){}
        Philosopher(const Philosopher& t){fns = t.fns;}
        ~Philosopher(){}
    public:
        static Philosopher *instance;
        static Philosopher *of(){
            if(instance) return instance;
            return (instance = new Philosopher());
        }
        void add(initializer_list<function<void()> >fs){
            for(auto iter = fs.begin();iter!=fs.end();iter++){
                fns.push_back(*iter);
            }
    
        }
        void add(function<void()> t){
            fns.push_back(t);
        }
        function<void() > get(size_t i){
            return fns[i];
        }
    };
     Philosopher *Philosopher::instance = 0;
    int main()
    {
        Philosopher::of()->add({functionA,functionB,functionC});
        cout<<"input Philosopher number:"<<endl;
        cin>>MaxN;
        cout<<"select method"<<endl;
        cout<<"1.lock"<<endl;
        cout<<"2.semaphore use mutex = 4"<<endl;
        cout<<"3.semaphore use odd even method"<<endl;
        unsigned int num;
        cin>>num;
    
        vector<thread> phils;
        for(size_t i=0;i<MaxN;i++){
            chopsticks[i] = 1;
        }
        switch (num) {
        case 1:
            for(size_t i=0;i<MaxN;i++){
                phils.push_back(thread(Philosopher::of()->get(0)));
            }
            break;
        case 2:
            for(size_t i=0;i<MaxN;i++){
    
                phils.push_back(thread(Philosopher::of()->get(1)));
            }
            break;
        case 3:
            for(size_t i=0;i<MaxN;i++){
    
                phils.push_back(thread(Philosopher::of()->get(2)));
            }
            break;
        default:
            break;
        }
    
        for(auto iter = phils.begin();iter!=phils.end();iter++){
            iter->join();
        }
        return 0;
    }
    

     

    展开全文
  • c++编程 mfc界面 操作系统 可以成功运行及测试
  • linux 哲学家进餐问题 c++

    千次阅读 2017-11-13 10:31:25
    #include #include #include #include #include #include #define N 5 #define LEFT i #define RIGHT (i+1)%N using namespace std; class Semaphore{  private:  sem_t sem;  public:
    #include<stdio.h>
    #include<stdlib.h>
    #include<pthread.h>
    #include<iostream>
    #include<unistd.h>
    #include<semaphore.h>
    #define N 5
    #define LEFT i
    #define RIGHT (i+1)%N
    using namespace std;
    class Semaphore{
       private:
          sem_t sem;
       public:
          Semaphore(int value=1){
              sem_init(&sem,0,value);
          }
          void P(){
              sem_wait(&sem);
          }
          void V(){
              sem_post(&sem);
          }
    };
    Semaphore mutex[N];
    pthread_t thread[N];
    int id[N];
    int add=0;
    void* solve(void*param){
        int i =*((int*)param);
        while(true){
           if(add>=30){
              cout<<"noodles is over"<<endl;
              break;
           }
           cout<<"philo"<<i<<"  thinking"<<endl;
           if(i%2==0){
              mutex[LEFT].P();
              mutex[RIGHT].P();
              cout<<"philo"<<i<<"  eatting"<<endl;
              add++;
              cout<<add<<endl;
              mutex[RIGHT].V();
              mutex[LEFT].V();
           }else{
              mutex[RIGHT].P();
              mutex[LEFT].P();
              cout<<"philo"<<i<<"  eatting"<<endl;
              add++;
              cout<<add<<endl;
              mutex[LEFT].V();
              mutex[RIGHT].V();
           }
           sleep(1);
        }
    }
    void thread_create(){
       int tmp;
       for(int i=0; i<N; i++){
          tmp=pthread_create(&thread[i],NULL,solve,&id[i]);
          if(tmp!=0){
              cout<<"thread"<<i<<"error"<<endl;
          }
       }
    }
    void thread_wait(){
        for(int i=0; i<N; i++){
           pthread_join(thread[i],NULL);
        }
    }
    int main(){
        for(int i=0; i<N; i++){
            id[i]=i;
        }
        thread_create();
        thread_wait();
        return 0;
    }
    展开全文
  • 哲学家进餐问题c++模拟实现,避免死锁的方法是奇数号哲学家先拿右边的筷子,偶数号先那左边的筷子,有详尽的注释。
  • 哲学家进餐问题代码动态描述,API显示,C++语言编写
  • 哲学家进餐C++程序

    2013-04-24 11:00:31
    规则:五个哲学家,他们交替地进行思考和进餐。他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起...
  • 首先c++11只有mutex与condition_variable这两个条件,是没有semaphore这个玩意的,因此借助mutex与condition_variable自己实现一个semaphore,然后解决os当中的哲学家进餐问题。 首先实现semaphore class Semaphore ...

    首先c++11只有mutex与condition_variable这两个条件,是没有semaphore这个玩意的,因此借助mutex与condition_variable自己实现一个semaphore,然后解决os当中的哲学家进餐问题。
    首先实现semaphore

    class Semaphore
    {
    public:
    Semaphore(int count =0):count(count)
    {}
    void Set(int n)
    {
    	count=n;
    }
    void Signal()
    {
    	unique_lock<mutex> lck(m_mutex);
    	count++;
    	cv.notify_all();
    }
    void Wait()
    {
    	unique_lock<mutex> lck(m_mutex);
    	if(count<=0)
    		cv.wait(lck);
    	count--;
    }
    
    private:
    mutex m_mutex;
    condition_variable cv;
    int count;
    };
    
    

    上述为实现的semaphore方法;
    则如何解决哲学家进餐问题呢?

    5 个沉默寡言的哲学家围坐在圆桌前,每人面前一盘意面。叉子放在哲学家之间的桌面上。(5 个哲学家,5 根叉子)

    所有的哲学家都只会在思考和进餐两种行为间交替。哲学家只有同时拿到左边和右边的叉子才能吃到面,而同一根叉子在同一时间只能被一个哲学家使用。每个哲学家吃完面后都需要把叉子放回桌面以供其他哲学家吃面。只要条件允许,哲学家可以拿起左边或者右边的叉子,但在没有同时拿到左右叉子时不能进食。

    假设面的数量没有限制,哲学家也能随便吃,不需要考虑吃不吃得下。

    设计一个进餐规则(并行算法)使得每个哲学家都不会挨饿;也就是说,在没有人知道别人什么时候想吃东西或思考的情况下,每个哲学家都可以在吃饭和思考之间一直交替下去。

    在这里插入图片描述
    三种实现方法:
    1、限制进餐人数

    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:
        std::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[l].unlock();
            lock[r].unlock();
        }
    private:
        std::mutex lock[5];
        std::mutex guid;
    };
    
    

    3、限定就餐策略
    规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号的哲学家则先拿起他右边的筷子,然后再去拿他左边的筷子。按此规定,将是1、2号哲学家竞争1号筷子,3、4号哲学家竞争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();
                pickLeftFork();
                pickRightFork();
            }else{
                lock[l].lock();
                lock[r].lock();
                pickLeftFork();
                pickRightFork();
            }
            
            eat();
            putRightFork();
            putLeftFork();
            lock[l].unlock();
            lock[r].unlock();
        }
    private:
        std::mutex lock[5];
    };
    
    

    转自lc,自我学习收藏用!

    展开全文
  • 文章目录哲学家进餐问题方法一:当两边的叉子都可用时才拿方法二:限制就餐的哲学家数量方法三:奇数先左后右,偶数先右后左 哲学家进餐问题 方法一:当两边的叉子都可用时才拿 方法二:限制就餐的哲学家数量 方法...


    哲学家进餐问题

    5 个沉默寡言的哲学家围坐在圆桌前,每人面前一盘意面。叉子放在哲学家之间的桌面上。(5 个哲学家,5 根叉子)

    所有的哲学家都只会在思考和进餐两种行为间交替。哲学家只有同时拿到左边和右边的叉子才能吃到面,而同一根叉子在同一时间只能被一个哲学家使用。每个哲学家吃完面后都需要把叉子放回桌面以供其他哲学家吃面。只要条件允许,哲学家可以拿起左边或者右边的叉子,但在没有同时拿到左右叉子时不能进食。

    假设面的数量没有限制,哲学家也能随便吃,不需要考虑吃不吃得下。
    设计一个进餐规则(并行算法)使得每个哲学家都不会挨饿;也就是说,在没有人知道别人什么时候想吃东西或思考的情况下,每个哲学家都可以在吃饭和思考之间一直交替下去。
    在这里插入图片描述

    为了方便测试这里选用leetcode的题库
    哲学家进餐

    哲学家进餐问题是并发编程中较为经典的一道题目,我们必须要保证互斥的情况下避免死锁以及饥饿。

    我们需要注意的地方有三点

    1. 只有拿到一双叉子后,哲学家才能吃饭
    2. 如果叉子已经被别人拿走,则需要等到他吃完放下后才能去拿
    3. 如果哲学家拿到了一只叉子,即使拿不到第二只,他也不会放下手中的叉子

    叉子只有5个,而哲学家也有5个,在最坏情况下每个哲学家都只能获取一只叉子,导致死锁。所以我们必须要保证至少有一个哲学家能够拿到两只叉子


    方法一:当两边的叉子都可用时才拿

    当某一个哲学家能够同时拿起左右两只叉子时,才让他拿,这样就能够保证不会因为每个科学家都只拿了一只叉子而导致死锁。

    为了保证能够同时拿起,我们需要对拿叉子这一步骤进行加锁,保证哲学家能够同时拿起一双叉子,而不会拿了一边后另一边被人抢走

    class DiningPhilosophers {
    public:
        DiningPhilosophers() 
        {}
    
        void wantsToEat(int philosopher,
                        function<void()> pickLeftFork,
                        function<void()> pickRightFork,
                        function<void()> eat,
                        function<void()> putLeftFork,
                        function<void()> putRightFork) 
        {
            //对拿叉子进行这一流程进行加锁,保证其能同时拿起一双,而不会被其他人抢走
            _lock.lock();
            _fork[philosopher].lock();
            _fork[(philosopher + 1) % 5].lock();
    		_lock.unlock();
    		
    		//拿起左右叉子
            pickLeftFork();	
            pickRightFork();
    
            eat();	//吃饭
            
    		//放下左右叉子
            putLeftFork();
            putRightFork();
            
            //解锁,让其他人获取叉子
            _fork[philosopher].unlock();
            _fork[(philosopher + 1) % 5].unlock();
        }
    
    private:
        mutex _lock;	
        mutex _fork[5];
    };
    

    方法二:限制就餐的哲学家数量

    如果要保证至少有一个哲学家能够进餐,那么我们可以采用最简单粗暴的方法,限制人数,只要同时进餐的哲学家不超过四人时,即使在最坏情况下,也至少有一个哲学家能够拿到多出来的那一个叉子。

    我们需要用到一个计数器来表示当前就餐的人数,为了保证线程安全我们需要用到一个互斥锁和一个条件变量对其进行保护

    class DiningPhilosophers {
    public:
        DiningPhilosophers()
            :_count(0)
        {}
    
        void wantsToEat(int philosopher,
                        function<void()> pickLeftFork,
                        function<void()> pickRightFork,
                        function<void()> eat,
                        function<void()> putLeftFork,
                        function<void()> putRightFork) 
        {
            
            unique_lock<mutex> lock(_mtx);
            _cond.wait(lock, [this]()->bool{
                return _count < 4;
            });    //当就餐人数不超过四人的时候允许拿叉子
            ++_count;
    
            _fork[philosopher].lock();
            _fork[(philosopher + 1) % 5].lock();
            pickLeftFork();
            pickRightFork();
    
            eat();
    
            putLeftFork();
            putRightFork();
            _fork[philosopher].unlock();
            _fork[(philosopher + 1) % 5].unlock();
    
            --_count;
            _cond.notify_one();	//就餐完成,让下一个人进来就餐
        }
    
    private:
        mutex _fork[5];
        mutex _mtx;
        condition_variable _cond;
        int _count;
    };
    

    方法三:奇数先左后右,偶数先右后左

    由于餐桌是一个如下图的圆环,如果我们此时规定奇数位的哲学家先拿左边的叉子,再拿右边的叉子。而偶数位的哲学家先拿右边的再拿左边的,此时竞争情况如下图所示
    在这里插入图片描述
    此时2号和3号哲学家争抢3号叉子,4号和5号哲学家争抢5号叉子,1号没有竞争对手,直接获取叉子1。
    可以看到,在第一轮中所有哲学家先去争抢奇数叉子,抢到偶数叉子后再去争抢偶数叉子,这样就能够保证至少有一个科学家能够获得两只叉子

    class DiningPhilosophers {
    public:
        DiningPhilosophers()
        {}
    
        void wantsToEat(int philosopher,
                        function<void()> pickLeftFork,
                        function<void()> pickRightFork,
                        function<void()> eat,
                        function<void()> putLeftFork,
                        function<void()> putRightFork) 
        {
            //如果是奇数则先抢左后抢右
            if(philosopher & 1)
            {
                _fork[philosopher].lock();
                _fork[(philosopher + 1) % 5].lock();
                pickLeftFork();
                pickRightFork();
            }
            //如果是偶数则先抢右后抢左
            else
            {
                _fork[(philosopher + 1) % 5].lock();
                _fork[philosopher].lock();
                pickRightFork();
                pickLeftFork();
                
            }
            eat();  //吃饭
    
            putLeftFork();  //放下叉子
            putRightFork();
            _fork[philosopher].unlock();
            _fork[(philosopher + 1) % 5].unlock();
        }
    private:
        mutex _fork[5];
    };
    
    展开全文
  • 这是哲学家进餐问题c++程序,这里使用的进餐方式是只有当哲学家左右两边都有可用筷子时才可以进餐,如果只有一只左手筷子放下自己左手筷子。如果对其中函数有不理解的可以看我另一篇博客进程相关函数汇总解释,...
  • 哲学家进餐问题(linux下C/C++源码)

    千次阅读 2018-12-02 23:50:30
    哲学家进餐问题(linux下C/C++源码) 题目描述: 题目自行百度吧。 思路: 5个哲学家相当于5的线程,5支筷子相当于5把mutex锁。 假如他们都拿左手边的筷子,这时就容易发生死锁,即谁都就不了餐(震荡行为)。 此时...
  • 思路: 参考题解:...解法1:控制同时拿筷子的哲学家人数(不多于4个) class Semaphore { public: Semaphore(int count = 0): count_(count){} void Set(int count) { count_ =.
  • 操作系统课程中模拟哲学家进餐问题c++程序,MFC开发
  • OS的题目我还是写伪代码吧。(菜哭 void move(){ do{ think(); int i; for(i=0;i<5;++i){ bool temp=wait(chopsticks[i],chopsticks[(i+1)%5]); if(temp==true){ ... release(chopsticks[i],cho
  • C++利用多线程实现哲学家进餐问题(解决死锁)
  • 哲学家进餐问题

    2020-07-01 17:38:49
    问题描述: 5个哲学家围坐在一个圆桌上,每两个哲学家之间都有一只筷子,哲学家平时进行思考,只有当他们饥饿时,才拿起筷子吃饭。规定每个哲学家只能先取其左边筷子,然后取其右边筷子,然后才可以吃饭。 #include<...
  • 哲学家进餐问题.zip

    2021-07-29 17:38:22
    包含详细实现文档和结果截图,以及完整c++代码实现
  • 操作系统:哲学家进餐问题

    千次阅读 2019-12-21 20:35:34
    操作系统:哲学家进餐问题 问题描述: 有五个哲学家围坐在一张圆桌旁就餐,,圆桌上有五个碗和五只筷子,他们的生活方式就是交替地进行思考和进餐。平时每个哲学家独立思考问题,饥饿时便试图分别取其左右两侧的...
  • ``` #include #include #include #include #include using namespace std; std::mutex mu; std::mutex chopsticks[5]; const char THINKING = 0; const char WAITING = 1; ...
  • 平台:vc++6.0 win32 API 图形界面演示哲学家进餐问题
  • c++设计哲学家进餐问题的求解

    千次阅读 2018-05-22 22:55:22
    #include&lt;stdio.h&gt;#include&lt;stdlib.h&gt;#include&lt;pthread.h&gt;#include&lt;iostream&...#define N 5#define LEFT i#define RIGHT (i+1)%Nusing n...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 416
精华内容 166
关键字:

哲学家进餐问题c++

c++ 订阅