fine/coarse grain 多线程实践

#ifndef __COARSE__QUEUE__H__
#define __COARSE__QUEUE__H__
#ifdef _MSC_VER
	#if _MSC_VER > 1000
		#pragma once
	#endif
#endif

#include <queue>
#include <mutex>
#include <memory>
#include <condition_variable>

namespace stc{
	template <typename type>
	class coarse_queue{
		typedef std::shared_ptr<type>			shared_ptr;
		typedef std::queue<shared_ptr>			queue;
		typedef coarse_queue	<type>				self;
	public:
		coarse_queue()                = default;
		coarse_queue(const self&)     = delete;
		self& operator =(const self&) = delete;
		void wait_and_pop(type&);
		bool try_pop(type&);
		shared_ptr wait_and_pop();
		shared_ptr try_pop();
		void push(type);
		bool empty()const;
	private:
		queue				    m_queue;
		mutable std::mutex      m_mutex;
		std::condition_variable m_cv;
	};

	template <typename type>
	void coarse_queue<type>::wait_and_pop(type& value){
		std::unique_lock<std::mutex> lock(m_mutex);
		m_cv.wait(lock, [this] { return !m_queue.empty(); });
		value = std::move(*(m_queue.front()));
		m_queue.pop();
	}

	template <typename type>
	bool coarse_queue<type>::try_pop(type& value){
		std::lock_guard<std::mutex> lock(m_mutex);
		if (m_queue.empty()) return (false);//if the queue is empty then return false to the caller
		value = std::move(*(m_queue.front()));
		m_queue.pop();
		return (true);
	}

	template <typename type>
	typename coarse_queue<type>::shared_ptr
			coarse_queue<type>::wait_and_pop(){
		std::unique_lock<std::mutex> lock(m_mutex);
		m_cv.wait(lock, [this] {return !m_queue.empty(); });
		shared_ptr res = m_queue.front();
		m_queue.pop();
		return (res);
	}

	template <typename type>
	typename coarse_queue<type>::shared_ptr
		coarse_queue<type>::try_pop(){
		std::lock_guard<std::mutex> lock(m_mutex);
		if (m_queue.empty()) return false;
		shared_ptr res = m_queue.front();
		m_queue.pop();
		return (res);
	}

	template <typename type>
	void coarse_queue<type>::push(type value){
		std::shared_ptr<type> item(std::make_shared<type>(value));
		std::lock_guard<std::mutex> lock(m_mutex);
		m_queue.push(item);
		m_cv.notify_one();
	}

	template <typename type>
	bool coarse_queue<type>::empty()const{
		std::lock_guard<std::mutex> lock(m_mutex);
		return (m_queue.empty());
	}


}

#endif

#ifndef __FINE__QUEUE__H__
#define __FINE__QUEUE__H__

#ifdef _MSC_VER
	#if _MSC_VER > 1000
		#pragma once
	#endif
#endif

#include <memory>
#include <mutex>
#include <condition_variable>

namespace stc{

	template <typename type>
	struct list_node{
		std::unique_ptr<type> m_next;
		std::shared_ptr<type> m_data;
		list_node() :m_next(NULL){}
	}; 

	template <typename type>
	class fine_queue{
		typedef fine_queue<type>		  self;
		typedef std::shared_ptr<type> shared_ptr;
		typedef list_node<type>		  list_node;
	public:
		fine_queue();
		fine_queue(const self&)		  = delete;
		self& operator =(const self&) = delete;
	public:
		void push(type);	
		bool empty()const;
		bool try_pop(type&);
		std::shared_ptr<type> try_pop();
		std::shared_ptr<type> wait_and_pop();
		void wait_and_pop(type&);
	private:
		list_node* get_tail();
		std::unique_ptr<list_node> pop_head();
		std::unique_lock<std::mutex> wait_for_data();
		std::unique_ptr<list_node> wait_pop_head();
		std::unique_ptr<list_node> wait_pop_head(type&);
		std::unique_ptr<list_node> try_pop_head();
		std::unique_ptr<list_node> try_pop_head(type&);
	private:
		list_node*					 m_tail;
		mutable std::mutex			 m_head_mutex;
		mutable std::mutex		     m_tail_mutex;
		std::unique_ptr<list_node>   m_head;
		std::condition_variable		 m_cv;
	};

	template <typename type>
	fine_queue<type>::fine_queue()
		:m_head(new list_node){
		m_tail = m_head.get();
	}

	template <typename type>
	void fine_queue<type>::push(type value){
		shared_ptr item(std::make_shared<type>(value));
		std::unique_ptr<list_node> node(new list_node);
		{
			std::lock_guard<std::mutex> lock(m_tail_mutex);
			m_tail->m_data	= item;
			list_node* next = node.get();
			m_tail->m_next	= std::move(node);
			m_tail			= next;
		}
		m_cv.notify_one();
	}

	template <typename type>
	typename fine_queue<type>::list_node*
		fine_queue<type>::get_tail(){
		std::lock_guard<std::mutex> lock(m_tail);
		return (m_tail);
	}

	template <typename type>
	std::unique_ptr<list_node<type> > 
		fine_queue<type>::pop_head(){
		std::unique_ptr<list_node> o_node = std::move(m_head);
		m_head = o_node->m_next;
		return (o_node);
	}

	template <typename type>
	std::unique_lock<std::mutex> fine_queue<type>::wait_for_data(){
		std::unique_lock<std::mutex> lock(m_head_mutex);
		m_cv.wait(lock, [this] { return this->m_head.get() != get_tail(); });
		return (std::move(lock));
	}

	template <typename type>
	std::unique_ptr<list_node<type> > fine_queue<type>::wait_pop_head(){
		std::unique_lock<std::mutex> lock(wait_for_data());
		return (pop_head());
	}

	template <typename type> 
	std::unique_ptr<list_node<type> > fine_queue<type>::wait_pop_head(type& value){
		std::unique_lock<std::mutex> lock(wait_for_data);
		value = std::move(*m_head);
		return (pop_head());
	}

	template <typename type>
	std::shared_ptr<type> fine_queue<type>::wait_and_pop(){
		std::unique_ptr<list_node> res = this->wait_pop_head();
		return (res->m_data);
	}

	template <typename type>
	void fine_queue<type>::wait_and_pop(type& value){
		wait_pop_head(value);
	}

	template <typename type>
	std::unique_ptr<list_node<type> > fine_queue<type>::try_pop_head(){
		std::lock_guard<std::mutex> lock(m_head_mutex);
		if (m_head.get() == get_tail())
			return (std::unique_ptr<list_node>());
		return (pop_head());
	}

	template <typename type>
	std::unique_ptr<list_node<type> > fine_queue<type>::try_pop_head(type& value){
		std::lock_guard<std::mutex> lock(m_head_mutex);
		if (m_head.get() == get_tail())
			return (std::unique_ptr<list_node>());
		value = std::move(*m_head);
		return (pop_head());
	}

	template <typename type>
	std::shared_ptr<type> fine_queue<type>::try_pop(){
		std::unique_ptr<list_node> res = try_pop_head();
		return res ? (res->m_data) : (std::shared_ptr<type>());
	}

	template <typename type>
	bool fine_queue<type>::try_pop(type& value){
		const std::unique_ptr<list_node> res = try_pop_head(value);
		return (res);
	}

	template <typename type>
	bool fine_queue<type>::empty()const{
		std::lock_guard<std::mutex> lock(m_head_mutex);
		return (m_head.get() == get_tail());
	}

}

#endif


你可能感兴趣的:(fine/coarse grain 多线程实践)