天天看點

linux 程序 互斥鎖,linux之mutex(互斥鎖)

在Posix Thread中定義有一套專門用于線程同步的mutex函數

1. 建立和銷毀 有兩種方法建立互斥鎖,靜态方式和動态方式。POSIX定義了一個宏PTHREAD_MUTEX_INITIALIZER來靜态初始化互斥鎖,方法如下: pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 在LinuxThreads實作中,pthread_mutex_t是一個結構,而PTHREAD_MUTEX_INITIALIZER則是一個結構常量。

動态方式是采用pthread_mutex_init()函數來初始化互斥鎖,API定義如下: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) 其中mutexattr用于指定互斥鎖屬性(見下),如果為NULL則使用預設屬性。

pthread_mutex_destroy ()用于登出一個互斥鎖,API定義如下: int pthread_mutex_destroy(pthread_mutex_t *mutex) 銷毀一個互斥鎖即意味着釋放它所占用的資源,且要求鎖目前處于開放狀态。由于在Linux中,互斥鎖并不占用任何資源,是以LinuxThreads中的 pthread_mutex_destroy()除了檢查鎖狀态以外(鎖定狀态則傳回EBUSY)沒有其他動作。

2. 互斥鎖屬性 互斥鎖的屬性在建立鎖的時候指定,在LinuxThreads實作中僅有一個鎖類型屬性,不同的鎖類型在試圖對一個已經被鎖定的互斥鎖加鎖時表現不同。目前(glibc2.2.3,linuxthreads0.9)有四個值可供選擇:

* PTHREAD_MUTEX_TIMED_NP,這是預設值,也就是普通鎖。當一個線程加鎖以後,其餘請求鎖的線程将形成一個等待隊列,并在解鎖後按優先級獲得鎖。這種鎖政策保證了資源配置設定的公平性。

* PTHREAD_MUTEX_RECURSIVE_NP,嵌套鎖,允許同一個線程對同一個鎖成功獲得多次,并通過多次unlock解鎖。如果是不同線程請求,則在加鎖線程解鎖時重新競争。

* PTHREAD_MUTEX_ERRORCHECK_NP,檢錯鎖,如果同一個線程請求同一個鎖,則傳回EDEADLK,否則與PTHREAD_MUTEX_TIMED_NP類型動作相同。這樣就保證當不允許多次加鎖時不會出現最簡單情況下的死鎖。

* PTHREAD_MUTEX_ADAPTIVE_NP,适應鎖,動作最簡單的鎖類型,僅等待解鎖後重新競争。

3.鎖操作 鎖操作主要包括加鎖pthread_mutex_lock()、解鎖pthread_mutex_unlock()和測試加鎖 pthread_mutex_trylock()三個,不論哪種類型的鎖,都不可能被兩個不同的線程同時得到,而必須等待解鎖。對于普通鎖和适應鎖類型,解鎖者可以是同程序内任何線程;而檢錯鎖則必須由加鎖者解鎖才有效,否則傳回EPERM;對于嵌套鎖,文檔和實作要求必須由加鎖者解鎖,但實驗結果表明并沒有這種限制,這個不同還沒有得到解釋。在同一程序中的線程,如果加鎖後沒有解鎖,則任何其他線程都無法再獲得鎖。

int pthread_mutex_lock(pthread_mutex_t *mutex)

int pthread_mutex_unlock(pthread_mutex_t *mutex)

int pthread_mutex_trylock(pthread_mutex_t *mutex)

pthread_mutex_trylock()語義與pthread_mutex_lock()類似,不同的是在鎖已經被占據時傳回EBUSY而不是挂起等待。

4. 其他 POSIX 線程鎖機制的Linux實作都不是取消點,是以,延遲取消類型的線程不會因收到取消信号而離開加鎖等待。值得注意的是,如果線程在加鎖後解鎖前被取消,鎖将永遠保持鎖定狀态,是以如果在關鍵區段内有取消點存在,或者設定了異步取消類型,則必須在退出回調函數中解鎖。 這個鎖機制同時也不是異步信号安全的,也就是說,不應該在信号處理過程中使用互斥鎖,否則容易造成死鎖。 互斥鎖屬性使用互斥鎖(互斥)可以使線程按順序執行。通常,互斥鎖通過確定一次隻有一個線程執行代碼的臨界段來同步多個線程。互斥鎖還可以保護單線程代碼。 要更改預設的互斥鎖屬性,可以對屬性對象進行聲明和初始化。通常,互斥鎖屬性會設定在應用程式開頭的某個位置,以便可以快速查找和輕松修改。表 4–1列出了用來處理互斥鎖屬性的函數。 表 4–1 互斥鎖屬性例程 操作      相關函數說明 初始化互斥鎖屬性對象      pthread_mutexattr_init 文法 銷毀互斥鎖屬性對象      pthread_mutexattr_destroy 文法 設定互斥鎖範圍      pthread_mutexattr_setpshared 文法 擷取互斥鎖範圍      pthread_mutexattr_getpshared 文法 設定互斥鎖的類型屬性      pthread_mutexattr_settype 文法 擷取互斥鎖的類型屬性      pthread_mutexattr_gettype 文法 設定互斥鎖屬性的協定      pthread_mutexattr_setprotocol 文法 擷取互斥鎖屬性的協定      pthread_mutexattr_getprotocol 文法 設定互斥鎖屬性的優先級上限      pthread_mutexattr_setprioceiling 文法 擷取互斥鎖屬性的優先級上限      pthread_mutexattr_getprioceiling 文法 設定互斥鎖的優先級上限      pthread_mutex_setprioceiling 文法 擷取互斥鎖的優先級上限      pthread_mutex_getprioceiling 文法 設定互斥鎖的強健屬性      pthread_mutexattr_setrobust_np 文法 擷取互斥鎖的強健屬性      pthread_mutexattr_getrobust_np 文法 表 4–2中顯示了在定義互斥範圍時 Solaris 線程和 POSIX 線程之間的差異。 表 4–2 互斥鎖範圍比較 Solaris      POSIX      定義 USYNC_PROCESS      PTHREAD_PROCESS_SHARED      用于同步該程序和其他程序中的線程 USYNC_PROCESS_ROBUST      無 POSIX 等效項      用于在程序間可靠地同步線程 USYNC_THREAD      PTHREAD_PROCESS_PRIVATE      用于僅同步該程序中的線程