Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <array>
- #include <random>
- #include <chrono>
- #include <vector>
- #include <ctime>
- #include <exception>
- const int NumP=5;
- class Philosopher
- {
- public:
- Philosopher(int n_,int health_=200):n(n_),health(health_)
- {
- chops.first = n;
- chops.second = (n + 1) % NumP;
- randgen.seed((n+1)* static_cast<unsigned int>(std::time(nullptr)));
- for(int i=0;i<NumP;++i)
- {
- logtab[i]=[]
- (int n){std::string temp;while(n--)temp+="\t\t\t";return temp;}
- (i);//3 tabs for a coloumn, change as required
- }
- };
- void operator()(std::array<std::mutex,NumP>& locks)
- {
- while(true)
- {
- std::chrono::milliseconds sleep_time ((randgen()%10+1)*100),eat_time((randgen()%10+1)*100);
- log("Thinking");
- std::this_thread::sleep_for(sleep_time);
- bool hungry=true;
- int temp_health=health;
- int first,second;
- while(hungry)
- {
- bool choice =randgen() < (randgen.max()+1)/2 ;
- first =chops.first;
- second = chops.second;
- if(choice)//The order of choice becomes random
- std::swap(first,second);
- if(locks[first].try_lock())
- if(locks[second].try_lock())
- {
- log("Eating");
- std::this_thread::sleep_for(eat_time);
- hungry=false;
- break;
- }
- else locks[first].unlock();//Putting the first one down too
- std::this_thread::sleep_for(std::chrono::milliseconds(20));//Try again
- temp_health--;
- if(!temp_health)
- {
- log("Leaving");//Becasue of lack of food in the seminar!
- return;
- }
- }
- locks[first].unlock();
- locks[second].unlock();
- }
- }
- void log(const std::string& fooing)
- {
- while(!cout_lock.try_lock())
- std::this_thread::sleep_for(std::chrono::milliseconds(20));
- std::cout<<logtab[n]<<"Philosopher "<<n<<" "<<fooing<<std::endl;
- cout_lock.unlock();
- }
- private:
- int n;//'Roll' no. of the philosophers!
- std::pair<int,int> chops; // ^--- chops
- std::mt19937 randgen;//Typedef of the Mersenne Twister engine with some weird looking parameters
- int health;//Each philosopher tries to eat health no. of times and then gets annoyed and leaves.
- std::array<std::string,NumP> logtab;
- static std::mutex cout_lock;
- };
- std::mutex Philosopher::cout_lock;
- int main(int argc,char** argv)
- {
- std::array<std::mutex,NumP> chops;
- std::vector<std::thread> threads;
- for(int i=0;i<NumP;++i)
- threads.push_back
- (
- std::thread
- (
- Philosopher(i),
- std::ref(chops)
- )
- );
- for(auto& t:threads)
- t.join();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment