Windows下條件變數的實現

來源:互聯網
上載者:User

條件變數是什嗎?

是一種同步對象。

 

條件變數有什麼用?

用於複雜的、多線程的、多核的程式中,實現多個線程間同步任務。

 

條件變數與其它同步對象的區別?

與事件、互斥鎖、segment等同步對象相比,條件變數最大的不同在於”條件“二字,其它同步對象的同步”條件“是固定的,如事件的被激發,互斥鎖被釋放,而條件變數的"條件"是完全自訂的,比如你可以實現當”張三賺了5塊錢、李四在看電視、奧巴馬訪問馬爾它“時,條件變數完成同步。所以說條件變數可用於複雜的同步任務。

 

Windows下有沒有條件變數?

簡單的答案是:沒有,Windows API沒有提供條件變數對象,這就是本文會存在的原因和要解決的問題。

複雜點的答案是:

  1. 使用Windows Vista之後的版本(Vista之後的版本提供了native的條件變數對象;
  2. 從開源庫中抽取;
  3. 你可以自已實現;

 

方案1不現實,因為現階段你的客戶大多數還是使用windows xp/2003以下的版本,而且Vista賣的也並不好;方案2可以參考ace庫,不過太多條件宏和不相關代碼,難以抽取使用(你不可能為了一個同步變數,而扯進整個龐大的ace庫吧);方案3難度更大,必須要熟悉多線程編程,還要考慮很多變態的細節,我就是採用方案3 - 自已實現的,因為網上沒有現成的,不得已而為之!而你就不必重新造輪子,直接copy下面的代碼到你的項目裡就可以直接使用了(只要你的項目是C++的)。

 

實現代碼如下:

 

class my_mutex<br />{<br />public:<br />my_mutex (bool be_initial_owner = false)<br />{<br />mutex_ = CreateMutexA (NULL, be_initial_owner, NULL);<br />}<br />~my_mutex (void)<br />{<br />CloseHandle (mutex_);<br />}<br />public:<br />int acquire (void)<br />{<br />DWORD ret = WaitForSingleObject (mutex_, INFINITE);<br />return ret == WAIT_OBJECT_0 ? 0 : -1;<br />}<br />int release (void)<br />{<br />BOOL bret = ReleaseMutex (mutex_);<br />return bret ? 0 : -1;<br />}<br />HANDLE handle (void)<br />{<br />return mutex_;<br />}<br />protected:<br />HANDLE mutex_;<br />};<br />class my_semaphore<br />{<br />public:<br />my_semaphore (long init_count, long max_count = (std::numeric_limits<long>::max)())<br />{<br />assert (init_count >= 0 && max_count > 0 && init_count <= max_count);<br />sema_ = CreateSemaphoreA (NULL, init_count, max_count, NULL);<br />}<br />~my_semaphore (void)<br />{<br />CloseHandle (sema_);<br />}<br />public:<br />int post (long count = 1)<br />{<br />BOOL bret = ReleaseSemaphore (sema_, count, NULL);<br />return bret ? 0 : -1;<br />}<br />int wait (long timeout = -1)<br />{<br />DWORD ret = WaitForSingleObject (sema_, timeout);<br />return ret == WAIT_OBJECT_0 ? 0 : -1;<br />}<br />HANDLE handle (void)<br />{<br />return sema_;<br />}<br />protected:<br />HANDLE sema_;<br />};<br />template<typename MUTEX><br />class my_condition<br />{<br />public:<br />my_condition (MUTEX &m)<br />: mutex_ (m)<br />, waiters_ (0)<br />, sema_ (0)<br />{<br />}<br />~my_condition (void)<br />{<br />}<br />public:<br />/// Returns a reference to the underlying mutex_;<br />MUTEX &mutex (void)<br />{<br />return mutex_;<br />}<br />/// Signal one waiting thread.<br />int signal (void)<br />{<br />// must hold the external mutex before enter<br />if ( waiters_ > 0 )<br />sema_.post ();<br />return 0;<br />}<br />/// Signal *all* waiting threads.<br />int broadcast (void)<br />{<br />// must hold the external mutex before enter<br />if ( waiters_ > 0 )<br />sema_.post (waiters_);<br />return 0;<br />}<br />int wait (unsigned long wait_time = -1)<br />{<br />// must hold the external mutex before enter<br />int ret = 0;<br />waiters_++;<br />ret = SignalObjectAndWait (mutex_.handle (), sema_.handle (), wait_time, FALSE);<br />mutex_.acquire ();<br />waiters_ --;<br />return ret == WAIT_OBJECT_0 ? 0 : -1;<br />}<br />protected:<br />MUTEX &mutex_;<br />/// Number of waiting threads.<br />long waiters_;<br />/// Queue up threads waiting for the condition to become signaled.<br />my_semaphore sema_;<br />};<br /> 

 

    以上代碼採用模板實現,變件變數類my_condition的模板參數是與條件變數配合使用的互斥量類型,為了方便直接使用,互斥量類型我也一併提供了: my_mutex。

 

    代碼我已在項目中測試使用過,如果發現問題,歡迎各路高手批評指正。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.