fine/coarse grain 多线程实践

来源:互联网 发布:linux 保存文件到本地 编辑:程序博客网 时间:2024/05/16 14:15
#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 callervalue = std::move(*(m_queue.front()));m_queue.pop();return (true);}template <typename type>typename coarse_queue<type>::shared_ptrcoarse_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_ptrcoarse_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


0 0
原创粉丝点击