執行緒同步與相互排斥 相互排斥鎖

2021-09-07 13:39:49 字數 3698 閱讀 4521

在多工作業系統中,同一時候執行的多個任務可能都須要使用同一種資源。這個過程有點類似於,公司部門裡。我在使用著印表機列印東西的同一時候(還沒有列印完)。別人剛好也在此刻使用印表機列印東西,假設不做不論什麼處理的話,列印出來的東西肯定是錯亂的。

以下我們用程式模擬一下這個過程。執行緒一須要列印「 hello 」,執行緒二須要列印「 world 」,不加不論什麼處理的話。列印出來的內容會錯亂:

[cpp]view plain

copy

#include 

#include 

#include 

// 印表機

void

printer(

char

*str)  

printf("\n"

);   

}  // 執行緒一

void

*thread_fun_1(

void

*arg)  

// 執行緒二

void

*thread_fun_2(

void

*arg)  

intmain(

void

)    

執行結果例如以下:

實際上,印表機是有做處理的,我在列印著的時候別人是不同意列印的。僅僅有等我列印結束後別人才同意列印。這個過程有點類似於,把印表機放在乙個房間裡,給這個房間安把鎖,這個鎖預設是開啟的。當 a 須要列印時,他先過來檢查這把鎖有沒有鎖著。沒有的話就進去,同一時候上鎖在房間裡列印。而在這時,剛好 b 也須要列印。b 相同先檢查鎖,發現鎖是鎖住的。他就在門外等著。而當 a 列印結束後,他會開鎖出來,這時候 b 才進去上鎖列印。

相互排斥鎖是一種簡單的加鎖的方法來控制對共享資源的訪問,相互排斥鎖僅僅有兩種狀態,即上鎖( lock )和解鎖( unlock )。

相互排斥鎖的操作流程例如以下:

1)在訪問共享資源後臨界區域前,對相互排斥鎖進行加鎖。

2)在訪問完畢後釋放相互排斥鎖導上的鎖。

3)對相互排斥鎖進行加鎖後,不論什麼其它試圖再次對相互排斥鎖加鎖的執行緒將會被堵塞,直到鎖被釋放。

相互排斥鎖的資料型別是:pthread_mutex_t

下面函式須要的標頭檔案:

#include

1)初始化相互排斥鎖int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);功能:

初始化乙個相互排斥鎖。

引數:

mutex

:設定相互排斥量的屬性,通常可採用預設屬性。就可以將 attr 設為 null。

能夠使用巨集 pthread_mutex_initializer 靜態初始化相互排斥鎖。比方:

pthread_mutex_t  mutex = pthread_mutex_initializer;
這樣的方法等價於使用 null 指定的 attr 引數呼叫 

pthread_mutex_init

() 來完畢動態初始化,不同之處在於 

pthread_mutex_initializer

巨集不進行錯誤檢查。

返回值:

成功:0。成功申請的鎖預設是開啟的。

失敗:非 0 錯誤碼

2)上鎖int pthread_mutex_lock(pthread_mutex_t *mutex);功能:

對相互排斥鎖上鎖。若相互排斥鎖已經上鎖,則呼叫者一直堵塞,直到相互排斥鎖解鎖後再上鎖。

引數:

mutex

返回值:

成功:0

失敗:非 0 錯誤碼

int pthread_mutex_trylock(pthread_mutex_t *mutex);

呼叫該函式時,若相互排斥鎖未加鎖,則上鎖。返回 0;若相互排斥鎖已加鎖,則函式直接返回失敗。即 ebusy。

3)解鎖

int pthread_mutex_unlock(pthread_mutex_t * mutex);

功能:

對指定的相互排斥鎖解鎖。

引數:

mutex

返回值:

成功:0

失敗:非 0 錯誤碼

4)銷毀相互排斥鎖int pthread_mutex_destroy(pthread_mutex_t *mutex);功能:

銷毀指定的乙個相互排斥鎖。相互排斥鎖在使用完成後,必需要對相互排斥鎖進行銷毀。以釋放資源。

引數:

mutex

返回值:

成功:0

失敗:非 0 錯誤碼

我們通過相互排斥鎖完好上面的樣例。演示樣例**例如以下:

[cpp]view plain

copy

#include 

#include 

#include 

pthread_mutex_t mutex; //相互排斥鎖

// 印表機

void

printer(

char

*str)  

printf("\n"

);   

pthread_mutex_unlock(&mutex); //解鎖

}  // 執行緒一

void

*thread_fun_1(

void

*arg)  

// 執行緒二

void

*thread_fun_2(

void

*arg)  

intmain(

void

)    

執行結果例如以下:

自旋鎖與相互排斥鎖之抉擇

自旋鎖和相互排斥鎖是多執行緒程式設計中的兩個重要概念。他們都能用來鎖定一些共享資源,以阻止影響資料一致性的併發訪問。可是他們之間確實存在差別,那麼這些差別是什麼?理論上,當乙個執行緒試圖獲取乙個被鎖定的相互排斥鎖時,該操作會失敗然後該執行緒會進入睡眠,這樣就能立即讓還有乙個執行緒執行。當持有相互排斥...

Linux同步與相互排斥應用(零) 基礎概念

當作業系統進入多道批處理系統時代以後。乙個系統中就存在多個任務,每乙個任務都依照一定的演算法進行排程來使用記憶體 cpu等共享資源。當當中乙個任務等待其它資源時,該任務能夠臨時睡眠,作業系統排程另外任務繼續執行額,這樣能夠使系統資源得到最大化利用。而無需像曾經單道批處理系統那樣僅僅有當乙個任務完畢之...

執行緒同步與鎖

二元訊號量和多元訊號量,是乙個變數,獲取 1,釋放 1,當變數處於 0的情形下才可以被獲取。乙個執行緒的獲取可以用另乙個執行緒來釋放。很像二元訊號量,但是釋放只能是本執行緒。臨界區是比互斥量更加嚴格的同步手段,訊號量和互斥量可以不同程序之間操作,也就是說 乙個程序建立了乙個互斥量或訊號量,另乙個程序...