SHOW:
|
|
- or go back to the newest paste.
| 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 | - | const int nump=5; |
| 9 | + | #include <exception> |
| 10 | const int NumP=5; | |
| 11 | class Philosopher | |
| 12 | {
| |
| 13 | - | Philosopher(int n_):n(n_) |
| 13 | + | |
| 14 | Philosopher(int n_,int health_=200):n(n_),health(health_) | |
| 15 | {
| |
| 16 | - | chops.second = (n<4)?n+1:0; |
| 16 | + | |
| 17 | - | randgen.seed(n); |
| 17 | + | chops.second = (n + 1) % NumP; |
| 18 | ||
| 19 | - | void operator()(std::array<std::mutex,nump>& locks) |
| 19 | + | randgen.seed((n+1)* static_cast<unsigned int>(std::time(nullptr))); |
| 20 | ||
| 21 | for(int i=0;i<NumP;++i) | |
| 22 | {
| |
| 23 | - | std::chrono::milliseconds sleep_time (randgen()%10000),eat_time(randgen()%10000); |
| 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 | - | int choice =randgen()%2; |
| 31 | + | |
| 32 | {
| |
| 33 | std::chrono::milliseconds sleep_time ((randgen()%10+1)*100),eat_time((randgen()%10+1)*100); | |
| 34 | - | if(choice) |
| 34 | + | |
| 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 | - | else locks[first].unlock(); |
| 44 | + | |
| 45 | - | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 45 | + | |
| 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 | - | void log(const std::string& data) |
| 53 | + | |
| 54 | hungry=false; | |
| 55 | - | while(!cout_lock.try_lock())std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 55 | + | break; |
| 56 | - | std::cout<<"Philosopher "<<n<<" "<<data<<std::endl; |
| 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 | - | int n; |
| 60 | + | if(!temp_health) |
| 61 | - | std::pair<int,int> chops; |
| 61 | + | {
|
| 62 | - | std::mt19937 randgen; |
| 62 | + | log("Leaving");//Becasue of lack of food in the seminar!
|
| 63 | return; | |
| 64 | } | |
| 65 | } | |
| 66 | - | int main() |
| 66 | + | |
| 67 | locks[second].unlock(); | |
| 68 | - | std::array<std::mutex,nump> chops; |
| 68 | + | |
| 69 | } | |
| 70 | - | for(int i=0;i<nump;++i) |
| 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 | } |