歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux平台用C++實現事件對象,同步線程

前文在Win32平台上用C++實現了事件對象Event,對線程進行同步(見 http://www.linuxidc.com/Linux/2011-12/49717.htm ),以達到期望目的。這次在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  
Copyright © Linux教程網 All Rights Reserved