韓三普
在Windows和Solaris中都提供進程與線程的互斥與同步機制。Windows提供了互斥對象、信號量對象和事件對象等三種內核同步對象和相應的系統調用 ,用於進程和線程同步。這些同步對象都有一個用戶指定的對象名稱,不同進程中用同樣的對象名稱來創建或打開對象,從而獲得該對象在本進程的句柄。而Solaris也相應的提供了幾個互斥同步對象,互斥鎖(Mutex Locks),讀寫鎖(Reader/writer (RW) locks),調度鎖(Dispatcher Locks),和信號量(Semaphores)。下面將一一對比或者說明。
1互斥對象(Mutex)
Windows中的互斥對象(Mutex)就是互斥信號量,在一個時刻只能被一個線程使用。它的相關API包括:CreateMutex、OpenMutex和ReleaseMutex 。
a) CreateMutex創建一個互斥對象,返回對象句柄。
b) OpenMutex打開並返回一個已存在的互斥對象句柄,用於後續訪問。
c) ReleaseMutex釋放對互斥對象的占用,使之成為可用。
在Solaris中,有Mutex locks(可稱做互斥鎖)和Windows中的互斥對象有相似的地方又有所不同,相比更加復雜。一個線程得到一個互斥鎖,就有兩種可能,一是自旋(spin),調用者就一直循環在那裡看是否該自旋鎖的保持者已經釋放了鎖。另一情況是(block)阻塞,線程被安排在一個睡眠隊列中,當鎖被釋放會發出信號給線程。自旋的好處是沒有上下文切換的開銷,效率非常高。而阻塞的優勢是可以釋放CPU給其它線程,但是需要上下文環境,並且比自旋鎖效率低一點。由此系統為Mutex提供了兩種鎖,自旋鎖和自適應鎖。自旋鎖就是采用自旋的方式,而自適應鎖是根據持有者的狀態,動態平衡是否采用自旋或者阻塞;如果鎖的持有者在運行態,線程得到的鎖就會是自旋的,如果不在運行態,就會是阻塞的,這樣充分發揮了兩種鎖的優點。
下面是Solaris提供的mutex locks的實現函數:
a) mutex_init(): 初始化一個鎖,只能選擇初始自旋或者自適應兩種的一種,默認是自適應。
b) mutex_enter():獲取互斥鎖
c) mutex_vector_enter(): 當鎖被持有或者是自旋時獲取互斥鎖
d) mutex_exit(): 釋放一個鎖
2信號量對象(Semaphore)
Windows中信號量對象(Semaphore)就是資源信號量,取值的取值在0到指定最大值之間,用於限制並發訪問的線程數。它的相關API包括:CreateSemaphore、OpenSemaphore和ReleaseSemaphore
a) CreateSemaphore創建一個信號量對象,在輸入參數中指定最大值和初值,返回對象句柄
b) OpenSemaphore返回一個已存在的信號量對象的句柄,用於後續訪問
c) ReleaseSemaphore釋放對信號量對象的占用
在Solaris中,內核也提供了信號量(Semaphores),可同步的使用可共享的資源。可對它進行P、V操作。P操作嘗試得到一個信號量,V操作釋放一個信號量。根據共享資源的數量初始化信號量的值。其原理和windows非常相似。
下面是Solaris提供的semaphores的實現函數:
a) sema_init(): 初始化信號量
b) sema_p(): P操作,嘗試獲取信號量
c) sema_v(): V操作,釋放信號量
d) sema_held(): 測試函數
e) sema_destroy(): 銷毀信號量
3事件對象(Event)
Windows提供的另一個互斥與同步對象是事件對象(Event),相當於“觸發器”,可用於通知一個或多個線程某事件的出現。它的相關的API包括:CreateEvent、OpenEvent、SetEvent、ResetEvent和PulseEvent
a) CreateEvent創建一個事件對象,返回對象句柄
b) OpenEvent返回一個已存在的事件對象的句柄,用於後續訪問
c) SetEvent和PulseEvent設置指定事件對象為可用狀態
d) ResetEvent設置指定事件對象為不可用狀態
4臨界區對象(Critical Section)
這是Windows環境提供的又一種同步互斥機制。只能在同一進程內使用的臨界區,同一進程內各線程對它的訪問是互斥進行的。把變量說明為CRITICAL_SECTION類型,就可作為臨界區使用。有關的API:
a) InitializeCriticalSection對臨界區對象進行初始化;
b) EnterCriticalSection等待占用臨界區的使用權,得到使用權時返回;
c) TryEnterCriticalSection非等待方式申請臨界區的使用權;申請失敗時,返回0;
d) LeaveCriticalSection釋放臨界區的使用權;
e) DeleteCriticalSection釋放與臨界區對象相關的所有系統資源;
5互鎖變量訪問
在Windows下,還可以采用互鎖變量訪問的方法實現同步互斥,它相當於硬件指令,對一個整數(進程內的變量或進程間的共享變量)進行操作。其目的是避免線程間切換的影響。有關的API:
a) InterlockedExchange進行32位數據的先讀後寫原子操作;
b) InterlockedCompareExchange依據比較結果進行賦值的原子操作;
c) InterlockedExchangeAdd先加後存結果的原子操作;
d) InterlockedDecrement先減1後存結果的原子操作;
e) InterlockedIncrement先加1後存結果的原子操作;
6調度鎖(Dispatcher Locks)
另外,在Solaris中還有一種鎖,可支持多CPU調度,叫做調度鎖(Dispatcher Locks)。內核的分配器Kernel dispatcher 查看線程的上下文環境來控制分配隊列它分為兩種類型,分別是普通的自旋鎖和CPU優先權提升的鎖。
7讀寫鎖(Reader/Writer Locks)
這也是Solaris提供的一種互斥同步機制,它適用於讀者寫者問題。比如:可在多線程同時讀取數據,只有一個線程寫數據時用到。如果有一個寫用戶得到這個鎖,所有讀用戶都不可以訪問。
基本實現方法:
a) rw_init(): 初始化讀寫鎖。
b) rw_enter():得到讀寫鎖
c) rw_exit(): 釋放讀寫鎖