基于Boost的数据处理器及线程安全队列、跨平台的信号量和互斥锁

近 半年主要是开发公司行情系统Feedhandler(一共十几个Feedhandler,包括沪深L1、L2,港股,国内期货,国际股票,国际期货 等。)。此系统要求跨平台、大吞吐量,超低延迟,属于CPU密集型系统。在项目过程中,有几个比较好的封装类,跟大家一起分享一下。以下所有源代码可至 http://download.csdn.net/detail/great3779/3998262 下载 一。基于Boost的跨平台锁。封装了Boost的mutex,提供了lock和unlock方法。代码示例如下:

  1. #pragma once  
  2.   
  3. // Author: Huangzhidan | great3779@sina.com   
  4. // copyright: @Wind Information Co., Ltd (Wind Info) ShangHai  
  5. // Create time: 2011-09-10  
  6. // 封装了boost的mutex,能跨平台使用。  
  7.   
  8. #include <boost/thread.hpp>  
  9.   
  10. class CWnLock  
  11. {  
  12. public:  
  13.     CWnLock(void) {}  
  14.     ~CWnLock(void) {}  
  15. public:  
  16.     virtual void lock() {m_lock.lock();}  
  17.     virtual void unlock() {m_lock.unlock();}  
  18. protected:  
  19.   boost::mutex m_lock;  
  20. };  


二。基于Boost的自动锁。相对之前的互斥锁,自动锁在发生异常时,能自动解锁,避免发生异常后,程序死锁。代码示例如下:

  1. // WnScopedLock.h  
  2. #pragma once  
  3.   
  4. // Author: Huangzhidan | great3779@sina.com   
  5. // copyright: @Wind Information Co., Ltd (Wind Info) ShangHai  
  6. // Create time: 2011-09-10  
  7. // 封装了boost的mutex的scoped_lock,能跨平台使用。相对于CWnLock,其优势在于发生异常时能自动解锁,避免线程死锁。  
  8.   
  9. #include "WnLock.h"  
  10.   
  11. class CWnScopedLock : public CWnLock  
  12. {  
  13. public:  
  14.   CWnScopedLock(CWnLock& mutex);  
  15.   virtual ~CWnScopedLock(void);  
  16. public:  
  17.   virtual void lock() {return m_pMutex->lock();}  
  18.   virtual void unlock() {return m_pMutex->unlock();}  
  19. private:  
  20.   CWnLock* m_pMutex;  
  21. };  
  22.   
  23. // WnScopedLock.cpp  
  24. #include "WnScopedLock.h"  
  25.   
  26. CWnScopedLock::CWnScopedLock(CWnLock& mutex)  
  27. {  
  28.   m_pMutex = &mutex;  
  29.   m_pMutex->lock();  
  30. }  
  31.   
  32. CWnScopedLock::~CWnScopedLock(void)  
  33. {  
  34.   m_pMutex->unlock();  
  35. }  


三。 基于Boost的事件信号通知。由于Boost原本的事件通知在使用时还需要带一把锁,使用过程也比较麻烦,不好理解。因此对其进行封装,封装后的 CWnEvent类使用时类似Windows下的CEvent类,且能跨平台使用,效率也比较高(使用了之前的互斥锁和自动锁)。代码示例如下:

  1. #pragma once  
  2.   
  3. // Author: Huangzhidan | great3779@sina.com   
  4. // copyright: @Wind Information Co., Ltd (Wind Info) ShangHai  
  5. // Create time: 2011-09-10  
  6. // 封装了boost的condition_variable,使其使用方法很接近Windows的Event。其优势在于能跨平台使用。  
  7.   
  8. #include "WnLock.h"  
  9. #include "WnScopedLock.h"  
  10. #include <boost/thread.hpp>  
  11. #include <boost/date_time/posix_time/posix_time.hpp>  
  12.   
  13. class CWnEvent  
  14. {  
  15. public:  
  16.     CWnEvent(void){}  
  17.   virtual ~CWnEvent(void){}  
  18.   
  19. public:  
  20.   void wait()  
  21.     {  
  22.         CWnScopedLock scoped_lock(m_lock);  
  23.         m_condition.wait(scoped_lock);    
  24.     }  
  25.   
  26.     bool timed_wait(int nMillSec)  
  27.     {  
  28.         CWnScopedLock scoped_lock(m_lock);  
  29.         return m_condition.timed_wait(scoped_lock, boost::posix_time::millisec(nMillSec));  
  30.     }  
  31.   
  32.     void notify_one() { m_condition.notify_one(); }  
  33.   
  34.     void notify_all() { m_condition.notify_all(); }  
  35.   
  36. private:  
  37.   CWnLock m_lock;  
  38.   boost::condition_variable_any m_condition;  
  39. };  


四。一个非常高效、使用简单、扩展性强的数据处理器。此数据处理器主要优点如下:
1. 跨平台
2. 将线程通信间比较难的线程安全、信号通知等机制均封装在对象中
3. 由于数据的传递完全依靠事件通知,因此数据的流转效率以及吞吐量均非常高(已经使用在公司海外股票FeedHandler上,吞吐量轻松突破每秒500,000个包)
4. 接口简单,使用非常方便(可参考BoostDemo程序)
5. 由于采用了模板技术以及运行时绑定技术,因此可扩展性非常强。(公司FeedHandler项目,已经在CDataHandler类上派生了数十个类,扩展性非常好)

以下是示例代码:

  1. #pragma once  
  2.   
  3. // Author: Huangzhidan | great3779@sina.com   
  4. // copyright: @Wind Information Co., Ltd (Wind Info) ShangHai  
  5. // Create time: 2011-09-10  
  6.   
  7. // 一个可用于线程间传递数据的类。此类的优势在于:  
  8. // 1. 跨平台  
  9. // 2. 将线程通信间比较难的线程安全、信号通知等机制均封装在对象中  
  10. // 3. 由于数据的传递完全依靠事件通知,因此数据的流转效率以及吞吐量均非常高(已经使用在公司海外股票FeedHandler上,吞吐量轻松突破每秒500,000个包)  
  11. // 4. 接口简单,使用非常方便(可参考BoostDemo程序)  
  12.   
  13. // 使用方法  
  14. // CDataHandler是一个基类,使用时定义子类对其进行继承。  
  15. // 继承类重写DataThread和DataFunc方法(一般情况下仅需重写DataFunc方法即可)  
  16.   
  17. #include "AtomQueue/WnQueue.h"  
  18. #include "Synchronous/WnEvent.h"  
  19. #include <boost/thread.hpp>  
  20.   
  21. // a pure virtual function  
  22. template <class T> class CDataHandler  
  23. {  
  24. public:  
  25.     CDataHandler(void) {Start();}  
  26.     virtual ~CDataHandler() {}  
  27.   
  28. public:  
  29.     // 单个通知接口(一般不需调用)  
  30.     void NotifyOne() {m_event.notify_one();}  
  31.   
  32.     // 全部通知接口(一般不需调用)  
  33.     void NotifyAll() {m_event.notify_all();}  
  34.   
  35.     // 推入流数据  
  36.     void Put(T& t)  
  37.     {  
  38.         m_record_set.push(t);  
  39.   
  40.         // 发送通知信号  
  41.         m_event.notify_one();  
  42.     }  
  43.   
  44.     // 获取缓冲区buffer size的接口  
  45.     int BufferSize() { return m_record_set.size(); }  
  46.   
  47. protected:  
  48.     // 处理数据的线程,可在运行时绑定  
  49.     virtual void DataThread()  
  50.     {  
  51.         while(true)  
  52.         {  
  53.             m_event.wait();  
  54.             while(!m_record_set.empty())  
  55.             {  
  56.                 T t;  
  57.                 if(m_record_set.get(t))  
  58.                 {  
  59.                     DataFunc(t);  
  60.                 }  
  61.             }  
  62.         }  
  63.     }  
  64.   
  65.     // 处理数据的函数,可在运行时绑定  
  66.     virtual void DataFunc(T& t) {}  
  67.   
  68. // 以下为内部函数  
  69. protected:  
  70.     // 开始运行  
  71.     void Start()  
  72.     {  
  73.         boost::thread t(&CDataHandler::DataThread, this);  
  74.     }  
  75.   
  76. protected:  
  77.     // 流数据集  
  78.     CWnQueue<T> m_record_set;  
  79.   
  80.     // 信号  
  81.     CWnEvent m_event;     
  82. };  


基于此类的派生类使用,可以参考源代码:
http://download.csdn.net/detail/great3779/3998262

posted @ 2013-11-29 13:02  孤火  阅读(787)  评论(0编辑  收藏  举报