boost 对于多线程应用的优化

多线程的应用开发,不管是客户端还是服务端都是能够极高提高性能的。如今CPU都是多核就更应该利用起来,但是不合理的代码会造成死锁宕机等,必须要注意以下几点:

1,多个子线程之间执行的逻辑最好是独立的,互不干涉的

2,子线程使用对象池创建销毁数据一定要加锁

3,子线程与主线程对同一数据尽量避免同时操作,如果不确定就需要加锁

4,线程之间的数据交互最好使用队列投递

现在我主要说的是跨线程队列,一般是使用加锁来保证队列数据正确,boost 增加了无锁队列,原理是使用原子操作队列交换,效率比使用锁的队列高很多

  1 #pragma once
  2 #pragma warning(disable:4996)
  3 
  4 #include <boost/thread/mutex.hpp>
  5 //#define USE_LIST
  6 
  7 #ifndef USE_LIST
  8 #include <queue>
  9 template<class T>
 10 class enable_queue : public std::queue<T>
 11 {
 12 public:
 13     void clear()
 14     {
 15         std::queue<T>::c.clear();
 16     }
 17 
 18     bool pop(T& v)
 19     {
 20         v = std::queue<T>::front();
 21         std::queue<T>::pop();
 22         return true;
 23     }
 24 };
 25 
 26 template<class T>
 27 class enable_safe_queue : public std::queue<T>
 28 {
 29 public:
 30     void clear()
 31     {
 32         std::queue<T>::c.clear();
 33     }
 34 
 35     bool pop(T& v)
 36     {
 37         v = std::queue<T>::front();
 38         std::queue<T>::pop();
 39         return true;
 40     }
 41 
 42     void safe_pop(T& v)
 43     {
 44         boost::lock_guard<boost::mutex> lock(m_mutex);
 45         this->pop(v);
 46     }
 47 
 48     void safe_push(T& v)
 49     {
 50         boost::lock_guard<boost::mutex> lock(m_mutex);
 51         std::queue<T>::push(v);
 52     }
 53 
 54     void safe_swap(enable_queue<T> q)
 55     {
 56         boost::lock_guard<boost::mutex> lock(m_mutex);
 57         swap(q);
 58     }
 59 
 60 private:
 61     boost::mutex m_mutex;
 62 };
 63 
 64 #else
 65 #include <list>
 66 
 67 template<class T>
 68 class enable_queue : public std::list<T>
 69 {
 70 public:    
 71     bool pop(T& v)
 72     {
 73         v = front();
 74         erase(begin());
 75         return true;
 76     }
 77 
 78     void push(T& v)
 79     {
 80         push_back(v);
 81     }
 82 };
 83 
 84 template<class T>
 85 class enable_safe_queue : public std::queue<T>
 86 {
 87 public:
 88     bool pop(T& v)
 89     {
 90         v = front();
 91         erase(begin());
 92         return true;
 93     }
 94 
 95     void push(T& v)
 96     {
 97         push_back(v);
 98     }
 99 
100     void safe_pop(T& v)
101     {
102         boost::lock_guard<boost::mutex> lock(m_mutex);
103         pop(v);
104     }
105 
106     void safe_push(T& v)
107     {
108         boost::lock_guard<boost::mutex> lock(m_mutex);
109         push(v);
110     }
111 
112     void safe_swap(enable_safe_queue<T> q)
113     {
114         boost::lock_guard<boost::mutex> lock(m_mutex);
115         swap(q);
116     }
117 private:
118     boost::mutex m_mutex;
119 };
120 
121 #endif
122 
123 
124 
125 #include <boost/lockfree/queue.hpp> 
126 #include <boost/lockfree/spsc_queue.hpp> 
127 #include <boost/atomic.hpp>
128 //无锁线程安全队列
129 
130 template<class T>
131 class fast_safe_queue : public boost::lockfree::spsc_queue<T>
132 {
133 public:
134     //queue必须先定义队列数量 过大会初始化很慢
135     fast_safe_queue(uint16_t maxqueue = std::numeric_limits<uint16_t>::max())
136         :boost::lockfree::spsc_queue<T>(maxqueue)
137     {
138 
139     }
140     ~fast_safe_queue()
141     {
142         //clear();
143     }
144 
145 
146     //必须在停止使用后调用 否则无法完全清理掉
147     void clear()
148     {
149         T temp;
150         while(!boost::lockfree::spsc_queue<T>::empty())
151         {
152             if(!boost::lockfree::spsc_queue<T>::pop(temp))
153                 break;
154         }
155     }
156 };
157 
158 template<class T>
159 class fast_count_queue : public boost::lockfree::spsc_queue<T>
160 {
161 public:
162     //queue必须先定义队列数量 过大会初始化很慢
163     fast_count_queue(uint16_t maxqueue = std::numeric_limits<uint16_t>::max())
164         :boost::lockfree::spsc_queue<T>(maxqueue),m_count(0)
165     {
166 
167     }
168     ~fast_count_queue()
169     {
170         //clear();
171     }
172 
173     //必须在停止使用后调用 否则无法完全清理掉
174     void clear()
175     {
176         T temp;
177         while(!boost::lockfree::spsc_queue<T>::empty())
178         {
179             if(!safe_pop(temp))
180                 break;
181         }
182     }
183 
184     bool safe_pop(T& v)
185     {
186         if(boost::lockfree::spsc_queue<T>::pop(v))
187         {
188             m_count--;
189             return true;
190         }
191         return false;
192     }
193 
194     bool safe_push(const T& v)
195     {
196         if(boost::lockfree::spsc_queue<T>::push(v))
197         {
198             m_count++;
199             return true;
200         }
201         return false;
202     }
203 
204     int size()
205     {
206         return m_count;
207     }
208 
209 private:
210     boost::atomic_int m_count; 
211 };
212 
213 //释放资源时可能出问题
214 template<class T>
215 class fast_mutli_queue : public boost::lockfree::queue<T>
216 {
217 public:
218     //queue必须先定义队列数量 过大会初始化很慢
219     fast_mutli_queue(uint16_t maxqueue = std::numeric_limits<uint16_t>::max())
220         :boost::lockfree::queue<T>(maxqueue)
221     {
222 
223     }
224     ~fast_mutli_queue()
225     {
226         //clear();
227     }
228 
229 
230     //必须在停止使用后调用 否则无法完全清理掉
231     void clear()
232     {
233         T temp;
234         while(!boost::lockfree::queue<T>::empty())
235         {
236             if(!boost::lockfree::queue<T>::pop(temp))
237                 break;
238         }
239     }
240 };
enable_queue.h

对于boost的线程池推荐使用threadpool,可以自己在网上找到源代码,需要少量修改,注意在退出时有个线程未退出导致的内存泄露的BUG

 

posted @ 2015-07-06 15:29  飞鱼云  阅读(981)  评论(0编辑  收藏  举报