Ex10: CPP code working
This commit is contained in:
		
							parent
							
								
									5fbca6ec01
								
							
						
					
					
						commit
						c5f7489717
					
				
					 4 changed files with 51 additions and 22 deletions
				
			
		|  | @ -9,11 +9,11 @@ int main() { | ||||||
| 	ThreadPool tp; | 	ThreadPool tp; | ||||||
| 
 | 
 | ||||||
| 	std::cout << "Add Producer" << std::endl; | 	std::cout << "Add Producer" << std::endl; | ||||||
| 	tp.newProducer(); | 	tp.addProducer(); | ||||||
| 
 | 
 | ||||||
| //	std::cout << "Add Consumers" << std::endl;
 | 	std::cout << "Add Consumers" << std::endl; | ||||||
| //	tp.newConsumer();
 | 	tp.addConsumer(); | ||||||
| //	tp.newConsumer();
 | 	tp.addConsumer(); | ||||||
| 
 | 
 | ||||||
| 	std::cout << "Run" << std::endl; | 	std::cout << "Run" << std::endl; | ||||||
| 	tp.run(); | 	tp.run(); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| // Shared_Queue.hh
 | // Shared_Queue.hh
 | ||||||
| #include <condition_variable> | #include <condition_variable> | ||||||
|  | #include <iostream> | ||||||
| #include <mutex> | #include <mutex> | ||||||
| #include <queue> | #include <queue> | ||||||
| 
 | 
 | ||||||
|  | @ -17,8 +18,9 @@ class SharedQueue | ||||||
| 
 | 
 | ||||||
| 		SharedQueue( const SharedQueue& other ) | 		SharedQueue( const SharedQueue& other ) | ||||||
| 		{ | 		{ | ||||||
|  | 			std::cout << "Copy Constructor SharedQueue" << std::endl; | ||||||
| 			// (Read)Lock the other queue for copying
 | 			// (Read)Lock the other queue for copying
 | ||||||
| 			std::unique_lock<std::mutex> other_lock(other._mutex); | 			std::unique_lock<std::mutex> other_lock(other._q_mutex); | ||||||
| 			_q = other._q; | 			_q = other._q; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -31,7 +33,7 @@ class SharedQueue | ||||||
| 		std::queue<T> _q; | 		std::queue<T> _q; | ||||||
| 
 | 
 | ||||||
| 		// Synchronisation
 | 		// Synchronisation
 | ||||||
| 		mutable std::mutex _q_mutex; | 		std::mutex _q_mutex; | ||||||
| 		mutable std::condition_variable _q_cv; | 		std::condition_variable _q_cv; | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -13,42 +13,65 @@ void producer( const int id, SharedQueue<int>& q, int max_t, int max_n ) | ||||||
| 	std::mt19937 mt(d()); | 	std::mt19937 mt(d()); | ||||||
| 	std::uniform_int_distribution<> distr(0., max_t); | 	std::uniform_int_distribution<> distr(0., max_t); | ||||||
| 
 | 
 | ||||||
| 	for ( int n = 0; n < max_n ; n++ ) | 	std::cout << " -- Starting Producer " << id << " (max_t: " << max_t << " max_n: " << max_n << ")" << std::endl; | ||||||
|  | 	for ( int n = 0; n < max_n ; ++n ) | ||||||
| 	{ | 	{ | ||||||
| 		n = distr(mt); | 		std::cout << " -- Producer " << id << "; n = " << n << std::endl; | ||||||
| 		std::this_thread::sleep_for(std::chrono::milliseconds(n)); | 
 | ||||||
|  | 		int l = distr(mt); | ||||||
|  | 		std::this_thread::sleep_for(std::chrono::milliseconds(l)); | ||||||
| 
 | 
 | ||||||
| 		// Lock q so we can push a new element
 | 		// Lock q so we can push a new element
 | ||||||
| 		std::unique_lock<std::mutex> lock(*q.mutex()); | 		std::unique_lock<std::mutex> lock(*q.mutex()); | ||||||
| 		q.queue()->push(n); | 		q.queue()->push(l); | ||||||
|  | 
 | ||||||
|  | 		std::cout << " -- Producer " << id << " pushed = " << l << std::endl; | ||||||
| 
 | 
 | ||||||
| 		// Notify one of the consumers
 | 		// Notify one of the consumers
 | ||||||
| 		q.cv()->notify_one(); | 		q.cv()->notify_one(); | ||||||
|  | 	 | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	std::cout << "Exiting Producer " << id << std::endl; | ||||||
| } | } | ||||||
| /*
 | void consumer( const int id, SharedQueue<int>& q, int max_t, int max_n ) | ||||||
| void consumer( const int id, SharedQueue<int& q, int max_t, int max_n ) |  | ||||||
| { | { | ||||||
|  | 	const int time_out = 5 ;// seconds
 | ||||||
| 	int b = 0; | 	int b = 0; | ||||||
| 	for ( int n = 0; n < max_n ; n++ ){ | 	 | ||||||
|  | 	std::cout << " -- Starting Consumer " << id << " (max_t: " << max_t << " max_n: " << max_n << ")" << std::endl; | ||||||
|  | 	for ( int n = 0; n < max_n ; n++ ) | ||||||
|  | 	{ | ||||||
|  | 		std::cout << " -- Consumer " << id << "; n = " << n << std::endl; | ||||||
| 		{ // Scope the lock of the queue
 | 		{ // Scope the lock of the queue
 | ||||||
| 			std::unique_lock<std::mutex> q_lock(q_mutex); | 			std::unique_lock<std::mutex> q_lock(*q.mutex()); | ||||||
| 
 | 
 | ||||||
| 			while ( q.queue()->empty() ) { | 			while ( q.queue()->empty() ) { | ||||||
| 				// Wait until we get a signal from the condition variable
 | 				// Wait until we get a signal from the condition variable
 | ||||||
| 				q_cv->wait(q_lock); | 				// or we reach a timeout
 | ||||||
|  | 				if ( q.cv()->wait_for(q_lock, std::chrono::seconds(time_out)) == std::cv_status::timeout ) | ||||||
|  | 				{ | ||||||
|  | 					// We reached the timeout
 | ||||||
|  | 					std::cout << " -- Consumer " << id << " timed out (" << time_out << "s)" << std::endl; | ||||||
|  | 
 | ||||||
|  | 					// this consumer does nothing after stopping the loop
 | ||||||
|  | 					// so we can return to break the loops
 | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// Get a value and pop it off
 | 			// Get a value and pop it off
 | ||||||
| 			b = q.front();  | 			b = q.queue()->front();  | ||||||
| 			q.pop(); | 			q.queue()->pop(); | ||||||
| 		}	 | 		}	 | ||||||
| 
 | 
 | ||||||
| 		//std::cout << " -- Consumer " << id << " : " << b << std::endl;
 | 		std::cout << " -- Consumer " << id << " read: " << b << std::endl; | ||||||
| 
 | 
 | ||||||
| 		// Slow down this thread to have a race between the consumers and the producers
 | 		// Slow down this thread to have a race between the consumers and the producers
 | ||||||
| 		// This only works after we have successfully read an int
 | 		// This only works after we have successfully read an int
 | ||||||
| 		std::this_thread::sleep_for(std::chrono::milliseconds(max_t)); | 		std::this_thread::sleep_for(std::chrono::milliseconds(max_t)); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	std::cout << "Exiting Consumer " << id << std::endl; | ||||||
| } | } | ||||||
| */ |  | ||||||
|  |  | ||||||
|  | @ -19,18 +19,22 @@ class ThreadPool | ||||||
| 			_consumers(), | 			_consumers(), | ||||||
| 			_producers() | 			_producers() | ||||||
| 		{}; | 		{}; | ||||||
| 		void newProducer( int max_t = 3000, int max_n = 10) | 		auto addProducer( int max_t = 3000, int max_n = 10) | ||||||
| 		{ | 		{ | ||||||
| 			std::thread * tp = new std::thread( producer, _producers.size(), std::ref(_q), max_t, max_n ); | 			std::thread * tp = new std::thread( producer, _producers.size(), std::ref(_q), max_t, max_n ); | ||||||
| 
 | 
 | ||||||
| 			_producers.push_back(tp); | 			_producers.push_back(tp); | ||||||
|  | 
 | ||||||
|  | 			return tp; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void newConsumer( int max_t = 2000, int max_n = 10) | 		auto addConsumer( int max_t = 2000, int max_n = 10) | ||||||
| 		{ | 		{ | ||||||
| 			std::thread * tp = new std::thread( consumer, _consumers.size(), std::ref(_q), max_t, max_n ); | 			std::thread * tp = new std::thread( consumer, _consumers.size(), std::ref(_q), max_t, max_n ); | ||||||
| 
 | 
 | ||||||
| 			_consumers.push_back(tp); | 			_consumers.push_back(tp); | ||||||
|  | 
 | ||||||
|  | 			return tp; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void run() | 		void run() | ||||||
|  |  | ||||||
		Reference in a new issue