最近回顧了下多線程的一些概念,主要的是線程間的同步以及互斥,簡單記錄下。
基本概念
2個基本概念:
同步:按預定的先後次序進行運行。比如:A.B.C3個線程,A先運行,然後B,然後C。 互斥:某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。 相關函數 關鍵區/臨界區 CRITICAL_SECTION 臨界區的使用比較簡單,基本步驟是: 初始化--進入--離開--銷毀 初始化:InitializeCriticalSection 進入:EnterCriticalSection 離開:LeaveCriticalSection 銷毀:DeleteCriticalSection
效率最高, 單進程內互斥最好。
有 線程所有權的概念,所以當前可進入臨界區的線程可以多次進入該臨界區,所以 不能做同步。
互斥量 Mutex 互斥量的使用基本步驟: 建立--等待對象--釋放--關閉 建立:CreateMutex 等待對象:WaitForSingleObject 釋放:ReleaseMutex 關閉:CloseHandle
跨進程,效率一般, 可用於保證只有一個執行個體被執行,主要是互斥用。
互斥量 有線程所有權,所以wait到的線程可以多次wait到,然後進入相關地區。
事件 Event 事件的基本使用步驟: 建立--set--等待--reset--關閉 建立:CreateEvent set:SetEvent 等待:WaitForSingleObject reset:ResetEvent 或者 在WaitForSingleObject後自動reset 關閉:CloseHandle
跨進程,set後就一直可以等待到,reset後就等待不到了。有一個 PulseEvent函數,蠻有趣的,作用是set後立即reset,相當於發射一個脈衝。
沒觸發就會一直卡在那兒,所以 可以用作同步。如果設定了自動重設,那麼wait之後,重設了,那就肯定無法再次進入。
訊號量 Semaphore 訊號量的和事件比較類似,基本使用步驟: 建立--釋放資源--等待--釋放資源--關閉 建立:CreateSemaphore 釋放資源:ReleaseSemaphore 等待:WaitForSingleObject 關閉:CloseHandle
跨進程,等待函數等待成功後,資源計數會-1。 如果當前資源計數足夠,那麼還可以等待到。注意: release的時候,釋放數量不可超過設定的資源總數。
類似事件,沒有資源就會卡在那兒。
比較分析 所有都可用於互斥 Event和Semaphore可用於同步 CriticalSection是非核心對象,相對更加高效
另外3個都是核心對象,可以跨進程,可用於保證只有一個執行個體運行 另外3個有對應的open函數 Event可自動Reset,方便 Semaphore可以指定資源數 Mutex可以很好的處理“遺棄”問題,即進程結束未釋放,會自動釋放,對多進程同時使用一個名稱的互斥量來說,這是一個好訊息 以上,大家各有優缺點,使用時需要根據實際情況選擇。