溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Linux中如何使用互斥量mutex

發(fā)布時(shí)間:2021-10-27 11:51:15 來(lái)源:億速云 閱讀:267 作者:小新 欄目:系統(tǒng)運(yùn)維

小編給大家分享一下Linux中如何使用互斥量mutex,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

##互斥量mutex

前文提到,系統(tǒng)中如果存在資源共享,線(xiàn)程間存在競(jìng)爭(zhēng),并且沒(méi)有合理的同步機(jī)制的話(huà),會(huì)出現(xiàn)數(shù)據(jù)混亂的現(xiàn)象。為了實(shí)現(xiàn)同步機(jī)制,Linux中提供了多種方式,其中一種方式為互斥鎖mutex(也稱(chēng)之為互斥量)。

互斥量的具體實(shí)現(xiàn)方式為:每個(gè)線(xiàn)程在對(duì)共享資源操作前都嘗試先加鎖,成功加鎖后才可以對(duì)共享資源進(jìn)行讀寫(xiě)操作,操作結(jié)束后解鎖。

Linux中如何使用互斥量mutex

互斥量不是為了消除競(jìng)爭(zhēng),實(shí)際上,資源還是共享的,線(xiàn)程間也還是競(jìng)爭(zhēng)的,只不過(guò)通過(guò)這種“鎖”機(jī)制就將共享資源的訪(fǎng)問(wèn)變成互斥操作,也就是說(shuō)一個(gè)線(xiàn)程操作這個(gè)資源時(shí),其它線(xiàn)程無(wú)法操作它,從而消除與時(shí)間有關(guān)的錯(cuò)誤。

從互斥量的實(shí)現(xiàn)機(jī)制我們可以看出,同一時(shí)刻,只能有一個(gè)線(xiàn)程持有該鎖。如果有同時(shí)有多個(gè)線(xiàn)程持有該鎖,那就沒(méi)有實(shí)際意義了。

但是,這種鎖機(jī)制不是強(qiáng)制的,互斥鎖實(shí)質(zhì)上是操作系統(tǒng)提供的一把“建議鎖”(又稱(chēng)“協(xié)同鎖”),建議程序中有多線(xiàn)程訪(fǎng)問(wèn)共享資源的時(shí)候使用該機(jī)制。

因此,即使有了mutex,其它線(xiàn)程如果不按照這種鎖機(jī)制來(lái)訪(fǎng)問(wèn)共享數(shù)據(jù)的話(huà),依然會(huì)造成數(shù)據(jù)混亂。所以為了避免這種情況,所有訪(fǎng)問(wèn)該共享資源的線(xiàn)程必須采用相同的鎖機(jī)制。

主要應(yīng)用函數(shù):

  • pthread_mutex_init函數(shù)

  • pthread_mutex_destroy函數(shù)

  • pthread_mutex_lock函數(shù)

  • pthread_mutex_trylock函數(shù)

  • pthread_mutex_unlock函數(shù)

以上5個(gè)函數(shù)的返回值都是:成功返回0,失敗返回錯(cuò)誤號(hào)。

在Linux環(huán)境下,類(lèi)型pthread_mutex_t其本質(zhì)是一個(gè)結(jié)構(gòu)體。但是為了簡(jiǎn)化理解,應(yīng)用時(shí)可忽略其實(shí)現(xiàn)細(xì)節(jié),簡(jiǎn)單當(dāng)成整數(shù)看待。mutex一般以下面方式定義:

pthread_mutex_t mutex;

變量mutex只有兩種取值1、0。

##pthread_mutex_init函數(shù)

函數(shù)原型:

int pthread_mutex_init(pthread_mutex_t restrict mutex, const pthread_mutexattr_t restrict attr);

函數(shù)作用:初始化一個(gè)互斥鎖(互斥量)mutex,初值可視為1;

參數(shù)介紹:

  • mutex:傳出參數(shù),調(diào)用時(shí)應(yīng)傳 &mutex給該函數(shù);

這里有個(gè)關(guān)鍵字比較特殊:restrict。它的作用只用于限制指針,告訴編譯器,所有修改該指針指向內(nèi)存中內(nèi)容的操作,只能通過(guò)本指針完成。不能通過(guò)除本指針以外的其他變量或指針修改。比如說(shuō),再定義個(gè)pthread_mutex_t的指針,將其賦值為mutex的值,想要用它來(lái)修改mutex所指向的內(nèi)存,這是不允許的。

  • attr:互斥量屬性。是一個(gè)傳入?yún)?shù),通常傳NULL,表示使用默認(rèn)屬性(即:線(xiàn)程間共享)。

對(duì)于互斥量mutex的初始化有兩種方式:

  • 靜態(tài)初始化:如果互斥鎖 mutex 是靜態(tài)分配的,即:定義為全局變量,或加了static關(guān)鍵字修飾,可以直接使用宏進(jìn)行初始化。e.g. pthead_mutex_t  muetx = PTHREAD_MUTEX_INITIALIZER;

  • 動(dòng)態(tài)初始化:如果互斥鎖mutex定義為局部變量,則應(yīng)采用動(dòng)態(tài)初始化。e.g. pthread_mutex_init(&mutex, NULL)

##pthread_mutex_destroy函數(shù)

函數(shù)原型:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

函數(shù)作用:銷(xiāo)毀一個(gè)互斥鎖

pthread_mutex_lock函數(shù)

函數(shù)原型:

int pthread_mutex_lock(pthread_mutex_t *mutex);

函數(shù)作用:

  • 對(duì)共享資源進(jìn)行加鎖??衫斫鉃閷utex--(或-1);

  • 如果加鎖不成功,則該線(xiàn)程將阻塞,直到持有該互斥量的其他線(xiàn)程解鎖為止。

注意:在訪(fǎng)問(wèn)共享資源前加鎖,訪(fǎng)問(wèn)結(jié)束后立即解鎖。鎖的“粒度”應(yīng)越小越好。

pthread_mutex_unlock函數(shù)

函數(shù)原型:

int pthread_mutex_trylock(pthread_mutex_t *mutex);

函數(shù)作用:

  • 對(duì)共享資源解鎖??衫斫鉃閷utex  ++(或+1);

  • 在解鎖的同時(shí),會(huì)將阻塞在該鎖上的所有線(xiàn)程全部喚醒,至于哪個(gè)線(xiàn)程先被喚醒,取決于優(yōu)先級(jí)、調(diào)度。默認(rèn)情況下:先阻塞的線(xiàn)程會(huì)先被喚醒。

##pthread_mutex_trylock函數(shù)

函數(shù)原型:

int pthread_mutex_trylock(pthread_mutex_t *mutex);

函數(shù)作用:對(duì)共享資源嘗試加鎖。它與pthread_mutex_lock函數(shù)的區(qū)別是,使用lock函數(shù)對(duì)共享資源進(jìn)行加鎖時(shí),如果加鎖不成功,則線(xiàn)程就阻塞;而如果使用trylock,則加鎖不成功時(shí)不會(huì)阻塞當(dāng)前線(xiàn)程,而是立即返回一個(gè)值來(lái)描述互斥鎖的狀況。

死鎖:

  • 線(xiàn)程試圖對(duì)同一個(gè)互斥量A加鎖兩次。

  • 線(xiàn)程1擁有A鎖,請(qǐng)求獲得B鎖;線(xiàn)程2擁有B鎖,請(qǐng)求獲得A鎖

#include <stdio.h> #include <unistd.h>#include <stdlib.h>#include <pthread.h>pthread_mutex_t mutex;void *tfn(void *arg) {    srand(time(NULL));     while(1) {         pthread_mutex_lock(&mutex);        printf("hello ");           // 標(biāo)準(zhǔn)輸出為共享資源         sleep(rand() % 3);          // 在此時(shí)會(huì)失去CPU         printf("world!\n");         pthread_mutex_unlock(&mutex);        sleep(rand() % 3);     }    return NULL; }int main(){    pthread_t tid;    int n = 5;     srand(time(NULL));     pthread_mutex_init(&mutex, NULL);    pthread_create(&tid, NULL, tfn, NULL);    while(n--) {         pthread_mutex_lock(&mutex);         printf("HELLO ");         sleep(rand() % 3);         printf("WORLD!\n");         pthread_mutex_unlock(&mutex);         sleep(rand() % 3);     }     pthread_cancel(tid);     pthread_join(tid, NULL);     pthread_mutex_destroy(&mutex);     return 0; }

以上是“Linux中如何使用互斥量mutex”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI