manasij7479

Dining Philosophers

Jul 30th, 2012
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <thread>
  3. #include <mutex>
  4. #include <array>
  5. #include <random>
  6. #include <chrono>
  7. #include <vector>
  8. #include <ctime>
  9. #include <exception>
  10. const int NumP=5;
  11. class Philosopher
  12. {
  13. public:
  14.     Philosopher(int n_,int health_=200):n(n_),health(health_)
  15.     {
  16.         chops.first = n;
  17.         chops.second = (n + 1) % NumP;
  18.        
  19.         randgen.seed((n+1)* static_cast<unsigned int>(std::time(nullptr)));
  20.  
  21.         for(int i=0;i<NumP;++i)
  22.         {
  23.             logtab[i]=[]
  24.                 (int n){std::string temp;while(n--)temp+="\t\t\t";return temp;}
  25.                     (i);//3 tabs for a coloumn, change as required
  26.         }  
  27.  
  28.     };
  29.     void operator()(std::array<std::mutex,NumP>& locks)
  30.     {
  31.         while(true)
  32.         {
  33.             std::chrono::milliseconds sleep_time ((randgen()%10+1)*100),eat_time((randgen()%10+1)*100);
  34.             log("Thinking");
  35.             std::this_thread::sleep_for(sleep_time);
  36.            
  37.             bool hungry=true;
  38.             int temp_health=health;
  39.            
  40.             int first,second;
  41.             while(hungry)
  42.             {
  43.                 bool choice =randgen() < (randgen.max()+1)/2 ;
  44.                 first =chops.first;
  45.                 second = chops.second;
  46.                 if(choice)//The order of choice becomes random
  47.                     std::swap(first,second);
  48.  
  49.                 if(locks[first].try_lock())
  50.                     if(locks[second].try_lock())
  51.                         {
  52.                             log("Eating");
  53.                             std::this_thread::sleep_for(eat_time);
  54.                             hungry=false;
  55.                             break;
  56.                         }
  57.                     else locks[first].unlock();//Putting the first one down too
  58.                 std::this_thread::sleep_for(std::chrono::milliseconds(20));//Try again
  59.                 temp_health--;
  60.                 if(!temp_health)
  61.                 {
  62.                     log("Leaving");//Becasue of lack of food in the seminar!
  63.                     return;
  64.                 }
  65.             }
  66.             locks[first].unlock();
  67.             locks[second].unlock();
  68.  
  69.         }
  70.  
  71.     }
  72.     void log(const std::string& fooing)
  73.     {
  74.         while(!cout_lock.try_lock())
  75.             std::this_thread::sleep_for(std::chrono::milliseconds(20));
  76.  
  77.         std::cout<<logtab[n]<<"Philosopher "<<n<<" "<<fooing<<std::endl;
  78.         cout_lock.unlock();
  79.     }
  80. private:
  81.     int n;//'Roll' no. of the philosophers!
  82.     std::pair<int,int> chops; // ^--- chops
  83.     std::mt19937 randgen;//Typedef of the Mersenne Twister engine with some weird looking parameters
  84.     int health;//Each philosopher tries to eat health no. of times and then gets annoyed and leaves.
  85.    
  86.     std::array<std::string,NumP> logtab;
  87.     static std::mutex cout_lock;
  88. };
  89. std::mutex Philosopher::cout_lock;
  90.  
  91. int main(int argc,char** argv)
  92. {
  93.     std::array<std::mutex,NumP> chops;
  94.     std::vector<std::thread> threads;
  95.    
  96.     for(int i=0;i<NumP;++i)
  97.         threads.push_back
  98.         (
  99.             std::thread
  100.             (
  101.                 Philosopher(i),
  102.                 std::ref(chops)
  103.             )
  104.         );
  105.     for(auto& t:threads)
  106.         t.join();
  107.     return 0;
  108. }
Advertisement
Add Comment
Please, Sign In to add comment