View difference between Paste ID: CCLpHYqH and Wj5d66pq
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
}