pthread mutex init 函式詳解

2021-10-05 05:44:30 字數 4269 閱讀 2114

linux下為了多執行緒同步,通常用到鎖的概念。

posix下抽象了乙個鎖型別的結構:ptread_mutex_t。通過對該結構的操作,來判斷資源是否可以訪問。顧名思義,加鎖(lock)後,別人就無法開啟,只有當鎖沒有關閉(unlock)的時候才能訪問資源。

即物件互斥鎖的概念,來保證共享資料操作的完整性。每個物件都對應於乙個可稱為" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有乙個執行緒訪問該物件。

使用互斥鎖(互斥)可以使執行緒按順序執行。通常,互斥鎖通過確保一次只有乙個執行緒執行**的臨界段來同步多個執行緒。互斥鎖還可以保護單執行緒**。

要更改預設的互斥鎖屬性,可以對屬性物件進行宣告和初始化。通常,互斥鎖屬性會設定在應用程式開頭的某個位置,以便可以快速查詢和輕鬆修改。

l 標頭檔案:

#include 

l 函式原型:

int pthread_mutex_init(pthread_mutex_t*restrict mutex,constpthread_mutexattr_t*restrict attr);

pthread_mutex_tmutex =pthread_mutex_initializer;

l 函式作用:

該函式用於c函式的多執行緒程式設計中,互斥鎖的初始化。

pthread_mutex_init() 函式是以動態方式建立互斥鎖的,引數attr指定了新建互斥鎖的屬性。如果引數attr為空(null),則使用預設的互斥鎖屬性,預設屬性為快速互斥鎖 。互斥鎖的屬性在建立鎖的時候指定,在linuxthreads實現中僅有乙個鎖型別屬性,不同的鎖型別在試圖對乙個已經被鎖定的互斥鎖加鎖時表現不同。

pthread_mutexattr_init() 函式成功完成之後會返回零,其他任何返回值都表示出現了錯誤。

函式成功執行後,互斥鎖被初始化為未鎖住態。

l 互斥鎖pthread_mutex_t的使用:

1. 互斥鎖建立和銷毀

有兩種方法建立互斥鎖,靜態方式動態方式。posix定義了乙個巨集pthread_mutex_initializer來靜態初始化互斥鎖,方法如下:

pthread_mutex_tmutex=pthread_mutex_initializer;

在linuxthreads實現中,pthread_mutex_t是乙個結構,而pthread_mutex_initializer則是乙個結構常量。

動態方式是採用pthread_mutex_init()函式來初始化互斥鎖,api定義如下:

intpthread_mutex_init(pthread_mutex_t*mutex, constpthread_mutexattr_t*mutexattr)

其中mutexattr用於指定互斥鎖屬性(見下),如果為null則使用預設屬性。

pthread_mutex_destroy()用於登出乙個互斥鎖,api定義如下:

intpthread_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.死鎖

死鎖主要發生在有多個依賴鎖存在時, 會在乙個執行緒試圖以與另乙個執行緒相反順序鎖住互斥量時發生. 如何避免死鎖是使用互斥量應該格外注意的東西。

總體來講, 有幾個不成文的基本原則:

對共享資源操作前一定要獲得鎖。

完成操作以後一定要釋放鎖。

盡量短時間地占用鎖。

如果有多鎖, 如獲得順序是abc連環扣, 釋放順序也應該是abc。

執行緒錯誤返回時應該釋放它所獲得的鎖。

下面是一段測試**,建立兩個執行緒,分別訪問全域性變數gnum,並且修改它,列印出來.

/* mutex.c */

#include #include #include #include /* 全域性變數 */

int gnum = 0;

/* 互斥量 */

pthread_mutex_t mutex;

/* 宣告執行緒執行服務程式. */

static void pthread_func_1(void);

static void pthread_func_2(void);

int main (void)

ret = pthread_create(&pt_2, //執行緒識別符號指標

null, //預設屬性

(void *)pthread_func_2, //執行函式

null); //無引數

if (ret != 0)

/*等待執行緒1、2的結束*/

pthread_join(pt_1, null);

pthread_join(pt_2, null);

printf ("main programme exit!/n");

return 0;

}/*執行緒1的服務程式*/

static void pthread_func_1(void)

pthread_exit(null);

}/*執行緒2的服務程式*/

static void pthread_func_2(void)

pthread_exit (null);

}

ngx process options函式詳解

ngx process options是初始化init cycle中的一些如 conf file,prefix,conf prefix等字段的功能,其方法的定義在src core nginx.c中,以下為詳細 主要功能是將ngx prefix,配置檔案的位置資訊,以及命令列引數的資訊初始化到cycl...

linux clock gettime函式詳解

注意 1.精確級別,納秒級別 原型long sys clock gettime clockid t which clock,struct timespec tp which clock引數解釋 clock realtime 系統實時時間,隨系統實時時間改變而改變,即從utc1970 1 1 0 0 ...

遞迴函式(詳例)

從函式棧的角度的運用 簡單的列印運用 includevoid function int n int main void function int n return 非空鍊錶的遞迴找最大值 lim findmax lim headptr 為了更好的理解遞迴的執行過程 在呼叫自生到最後時,if head...