Linux平台用C++实现事件对象,同步线程


前文在Win32平台上用C++实现了事件对象Event,对线程进行同步(见  ),以达到期望目的。这次在Linux平台上实现与之类似的事件对象。与其相关的一组API包括:pthread_mutex_init,pthread_cond_init,pthread_mutex_lock,pthread_cond_wait,pthread_mutex_unlock,pthread_cond_broadcast,pthread_cond_timedwait,pthread_cond_destroy,pthread_mutex_destroy。下边,是封装的事件对象类,以及测试代码。使用VS2005编辑,在虚拟机 Fedora 13中编译,测试通过。

MyEvent.h

  1. #ifndef My_Event_Header   
  2. #define My_Event_Header   
  3.   
  4. #include <iostream>   
  5. #include <pthread.h>   
  6. #include <errno.h>   
  7.   
  8. using namespace std;  
  9.   
  10. //---------------------------------------------------------------   
  11.   
  12. class CEventImpl  
  13. {  
  14. protected:  
  15.       
  16.     /* 
  17.      动态方式初始化互斥锁,初始化状态变量m_cond 
  18.     `bAutoReset  true   人工重置 
  19.                  false  自动重置 
  20.     */  
  21.     CEventImpl(bool manualReset);         
  22.       
  23.     /* 
  24.      注销互斥锁,注销状态变量m_cond 
  25.     */  
  26.     ~CEventImpl();  
  27.   
  28.     /* 
  29.      将当前事件对象设置为有信号状态 
  30.      若自动重置,则等待该事件对象的所有线程只有一个可被调度 
  31.      若人工重置,则等待该事件对象的所有线程变为可被调度 
  32.     */  
  33.     void SetImpl();  
  34.   
  35.     /* 
  36.      以当前事件对象,阻塞线程,将其永远挂起 
  37.      直到事件对象被设置为有信号状态 
  38.     */  
  39.     bool WaitImpl();  
  40.   
  41.     /* 
  42.      以当前事件对象,阻塞线程,将其挂起指定时间间隔 
  43.      之后线程自动恢复可调度 
  44.     */  
  45.     bool WaitImpl(long milliseconds);  
  46.   
  47.     /* 
  48.      将当前事件对象设置为无信号状态 
  49.     */  
  50.     void ResetImpl();  
  51.   
  52. private:  
  53.     bool            m_manual;  
  54.     volatile bool   m_state;  
  55.     pthread_mutex_t m_mutex;  
  56.     pthread_cond_t  m_cond;  
  57. };  
  58.   
  59. inline void CEventImpl::SetImpl()  
  60. {  
  61.     if (pthread_mutex_lock(&m_mutex))     
  62.         cout<<"cannot signal event (lock)"<<endl;  
  63.   
  64.     //设置状态变量为true,对应有信号   
  65.     m_state = true;  
  66.   
  67.     //cout<<"CEventImpl::SetImpl m_state = "<<m_state<<endl;   
  68.   
  69.     //重新激活所有在等待m_cond变量的线程   
  70.     if (pthread_cond_broadcast(&m_cond))  
  71.     {  
  72.         pthread_mutex_unlock(&m_mutex);  
  73.         cout<<"cannot signal event"<<endl;  
  74.     }  
  75.     pthread_mutex_unlock(&m_mutex);  
  76. }  
  77.   
  78. inline void CEventImpl::ResetImpl()  
  79. {  
  80.     if (pthread_mutex_lock(&m_mutex))     
  81.         cout<<"cannot reset event"<<endl;  
  82.   
  83.     //设置状态变量为false,对应无信号   
  84.     m_state = false;  
  85.   
  86.     //cout<<"CEventImpl::ResetImpl m_state = "<<m_state<<endl;   
  87.   
  88.     pthread_mutex_unlock(&m_mutex);  
  89. }  
  90.   
  91. //---------------------------------------------------------------   
  92.   
  93. class CMyEvent: private CEventImpl  
  94. {  
  95. public:  
  96.     CMyEvent(bool bManualReset = true);  
  97.     ~CMyEvent();  
  98.   
  99.     void Set();  
  100.     bool Wait();  
  101.     bool Wait(long milliseconds);  
  102.     bool TryWait(long milliseconds);  
  103.     void Reset();  
  104.   
  105. private:  
  106.     CMyEvent(const CMyEvent&);  
  107.     CMyEvent& operator = (const CMyEvent&);  
  108. };  
  109.   
  110.   
  111. inline void CMyEvent::Set()  
  112. {  
  113.     SetImpl();  
  114. }  
  115.   
  116. inline bool CMyEvent::Wait()  
  117. {  
  118.     return WaitImpl();  
  119. }  
  120.   
  121. inline bool CMyEvent::Wait(long milliseconds)  
  122. {  
  123.     if (!WaitImpl(milliseconds))  
  124.     {  
  125.         cout<<"time out"<<endl;  
  126.         return false;  
  127.     }  
  128.     else  
  129.     {  
  130.         return true;  
  131.     }  
  132. }  
  133.   
  134. inline bool CMyEvent::TryWait(long milliseconds)  
  135. {  
  136.     return WaitImpl(milliseconds);  
  137. }  
  138.   
  139. inline void CMyEvent::Reset()  
  140. {  
  141.     ResetImpl();  
  142. }  
  143.   
  144. #endif  
  • 1
  • 2
  • 3
  • 下一页

相关内容