Windows平臺下的線程同步

引子windows

這幾天在寫一個windows phone平臺上的service,因爲Windows phone 的內核是基於Windows NT的,這也意味着寫Windows Phone的Service代碼與Win32更接近了。安全

雖然功能不多,可是一旦release出去,就像潑出去的水,若是個人代碼出了Bug,用戶只有更新固件才能獲取更新,壓力仍是挺大。函數

主要的擔憂點是線程同步:性能

代碼註冊了一個系統的事件,當系統觸發事件時,會調用事件相應的callback函數,而此callback與main線程不在同一個線程,天然引起了線程同步的問題。spa

索性再次翻開《Windows via C++》,複習一下線程同步的基礎知識,寫完代碼與老外討論了一下,還存在一些細節問題,順手記錄一下,以便鞏固和回顧。線程

線程同步的本質在於保證某一個變量在被多個線程訪問時仍然保持一致性。對象

用戶模式下的線程同步:進程

用戶模式下有如下幾種同步的方式:事件

  • Interlocked系列函數。由於代碼執行的原子操做是一條CPU指令而不是一句代碼,一句 a++ 都是由幾條指令組成的。InterlockedXXX的一系列函數可以保證對資源的操做是原子性的。
  • CRITICAL_SECTION結構體,能夠用InitializeCriticalSection()和DeleteCriticalSection()函數來初始化和刪除結構體,而把須要同步的代碼放在EnterCriticalSection()與LeaveCriticalSection()之間。
  • SRWLock,用於區分讀取資源和寫入資源的線程,由於多個讀取線程同時訪問一個資源是線程安全的。

另外要注意的是:內存

  • volatile關鍵字保證CPU從內存中讀取數據而不是從寄存器中讀取數據。
  • CRITICAL_SECTION能保證操做時不會有其餘線程進入,固然本身也不會重入。
  • 不要長時間佔用鎖,在EnterCriticalSection中時間儘可能保持到最少。

使用內核對象進行線程同步:

內核對象包括:進程,線程,文件,事件,timer,信號量,互斥量等。而且有觸發/未觸發 兩種狀態。內核對象能夠用Handle類型表示。

  • WaitForSingleObject(handle, Time) 可讓線程等待到第一個參數指定的內核對象被觸發過,或者到達第二個參數指定的超時時間,能夠將時間設置爲INFINITE讓線程無限等待直到內核對象狀態變化,並且,不佔用CPU時間,此時的線程狀態是Wait,而不是Ready。
  • WaitForMultiObjects(),能夠等待多個內核對象的狀態變化。
  • 一般可讓WaitForSingle/MulitObject來等待事件對象,能夠用CreateEvent()來建立一個事件的內核對象,能夠經過SetEvent()改變事件的狀態,使用ResetEvent()重置事件狀態。
  • 可等待的timer內核對象,能夠用CreateWaitableTimer建立,使用SetWaitableTimer來觸發。
  • 信號量,能夠對資源進行計數。使用CreateSemaphore建立並設置最大計數,使用ReleaseSemaphore來減小資源計數。
  • 互斥量,確保一個線程獨佔一個資源。使用CreateMutex建立,使用ReleaseSemaphore來釋放。它比CRITICAL_SECTION性能差但能夠跨進程。

要注意的是:全部內核對象使用完成後都應該用CloseHandle關閉

 

這基本是跟Win32平臺的寫法一致了,只是手機的資源更緊張,要時刻考慮到電量的消耗。

相關文章
相關標籤/搜索