九色91_成人精品一区二区三区中文字幕_国产精品久久久久一区二区三区_欧美精品久久_国产精品99久久久久久久vr_www.国产视频

Hello! 歡迎來到小浪云!


嵌入式Linux:線程同步(互斥鎖)


avatar
小浪云 2025-04-19 22

linux線程的互斥鎖(mutex)是用于保護(hù)共享資源的同步機制,確保在多線程環(huán)境中,多個線程不會同時訪問或修改同一個資源,從而避免數(shù)據(jù)競爭或不一致的問題。

嵌入式Linux:線程同步(互斥鎖)

互斥鎖是一種二進(jìn)制鎖,也就是說它只有兩種狀態(tài):鎖定(locked)和解鎖(unlocked)。

當(dāng)一個線程想要訪問受保護(hù)的共享資源時,它首先必須嘗試鎖定互斥鎖,如果鎖已經(jīng)被其他線程持有,則它必須等待,直到鎖被釋放。

當(dāng)線程完成對資源的操作后,它需要解鎖互斥鎖,以便其他線程可以訪問該資源。

互斥鎖的工作原理:

鎖定(lock):線程調(diào)用pthread_mutex_lock(),如果互斥鎖已經(jīng)解鎖,則該線程成功鎖定,并進(jìn)入臨界區(qū)訪問共享資源;如果鎖已被其他線程占有,則當(dāng)前線程將阻塞,直到鎖被釋放。解鎖(unlock):線程完成對共享資源的操作后,調(diào)用pthread_mutex_unlock(),這會釋放鎖,其他被阻塞的線程將有機會鎖定并訪問該資源。

Linux下,線程互斥鎖主要通過POSIX線程庫(pthread)來實現(xiàn),通常的步驟包括:

初始化互斥鎖:使用pthread_mutex_init()或直接用靜態(tài)初始化PTHREAD_MUTEX_INITIALIZER。鎖定互斥鎖:在線程需要訪問共享資源前,使用pthread_mutex_lock()鎖定。訪問共享資源:執(zhí)行需要對共享資源的操作。解鎖互斥鎖:訪問結(jié)束后,使用pthread_mutex_unlock()解鎖。銷毀互斥鎖:使用pthread_mutex_destroy()銷毀互斥鎖,通常在不再使用該互斥鎖時進(jìn)行。

1、互斥鎖的初始化

互斥鎖在使用之前必須先進(jìn)行初始化操作。

可以通過兩種方式來初始化互斥鎖:靜態(tài)初始化和動態(tài)初始化。

1.1、靜態(tài)初始化

靜態(tài)初始化使用 PTHREAD_MUTEX_INITIALIZER 宏來初始化互斥鎖,這是一種常見且簡便的初始化方法。

無需顯式調(diào)用初始化函數(shù),適用于全局互斥鎖。

代碼語言:JavaScript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

在這種方式下,互斥鎖被設(shè)置為默認(rèn)屬性。靜態(tài)初始化不需要任何額外參數(shù),并且返回值是隱式的,不會返回錯誤碼。

1.2、動態(tài)初始化

動態(tài)初始化通過 pthread_mutex_init() 函數(shù)完成,適用于需要在運行時動態(tài)分配的互斥鎖,或需要自定義互斥鎖屬性的情況。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_t mutex;pthread_mutexattr_t attr;pthread_mutexattr_init(&attr);  // 初始化互斥鎖屬性// 初始化互斥鎖,第二個參數(shù)為屬性,如果不需要自定義屬性可以傳入 NULLint ret = pthread_mutex_init(&mutex, &attr);if (ret != 0) {    // 處理初始化失敗}pthread_mutexattr_destroy(&attr);  // 銷毀屬性

參數(shù):

mutex:指向 pthread_mutex_t 類型互斥鎖的指針。attr:互斥鎖的屬性指針,可以設(shè)置互斥鎖的行為。如果不需要自定義屬性,傳入 NULL 表示使用默認(rèn)屬性。

返回值:成功時返回 0,失敗時返回非零錯誤碼。常見錯誤碼包括:

EINVAL:attr 屬性無效。EBUSY:互斥鎖已經(jīng)被初始化。ENOMEM:內(nèi)存不足,無法分配資源。

2、互斥鎖加鎖與解鎖

2.1、互斥鎖加鎖

pthread_mutex_lock() 用于對互斥鎖加鎖。

如果互斥鎖已經(jīng)被其他線程鎖住,調(diào)用線程將進(jìn)入阻塞狀態(tài),直到該互斥鎖被解鎖。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_lock(&mutex);  // 加鎖

參數(shù):mutex 是指向要加鎖的 pthread_mutex_t 互斥鎖對象指針

返回值:成功時返回 0。如果出現(xiàn)錯誤,返回非零錯誤碼:

EINVAL:互斥鎖無效。EDEADLK:線程試圖遞歸加鎖一個非遞歸互斥鎖(導(dǎo)致死鎖)。2.2、互斥鎖解鎖

pthread_mutex_unlock() 用于解鎖已經(jīng)加鎖的互斥鎖。

如果其他線程正等待此互斥鎖,它將被喚醒并獲取鎖。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_unlock(&mutex);  // 解鎖

參數(shù):mutex 是指向要解鎖的 pthread_mutex_t 互斥鎖對象的指針。

返回值:成功時返回 0。可能的錯誤碼:

EINVAL:互斥鎖無效。EPERM:當(dāng)前線程沒有持有該互斥鎖。

3、非阻塞加鎖

pthread_mutex_trylock() 是一種非阻塞加鎖操作。

如果互斥鎖已經(jīng)被其他線程鎖住,它不會阻塞,而是立即返回錯誤碼 EBUSY。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

int try_lock_example() {    int ret = pthread_mutex_trylock(&mutex);    if (ret == 0) {        // 鎖定成功        printf("鎖定成功!n");        pthread_mutex_unlock(&mutex);  // 解鎖    } else if (ret == EBUSY) {        // 鎖定失敗,互斥鎖已被其他線程持有        printf("鎖定失敗,互斥鎖被占用。n");    } else {        // 其他錯誤        printf("嘗試鎖定時出現(xiàn)錯誤。n");    }    return 0;}

參數(shù):mutex 是指向要加鎖的 pthread_mutex_t 互斥鎖對象的指針。

返回值:

0:成功加鎖。EBUSY:互斥鎖已經(jīng)被其他線程持有,無法加鎖。EINVAL:互斥鎖無效。

4、銷毀互斥鎖

使用完互斥鎖后,應(yīng)該通過 pthread_mutex_destroy() 釋放與之相關(guān)的資源。

銷毀互斥鎖之前,確保它已經(jīng)被解鎖。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_destroy(&mutex);

參數(shù):mutex 是指向要銷毀的 pthread_mutex_t 互斥鎖對象的指針。

返回值:

0:成功銷毀。EINVAL:互斥鎖無效或未被初始化。EBUSY:互斥鎖仍被鎖定,不能銷毀。

銷毀互斥鎖后,它不能再被使用,除非重新初始化。

5、互斥鎖死鎖問題

如果一個線程在鎖定互斥鎖后由于某種原因沒有解鎖(如忘記調(diào)用pthread_mutex_unlock()或在臨界區(qū)中發(fā)生異常終止),其他線程將永遠(yuǎn)無法獲得該鎖,導(dǎo)致系統(tǒng)卡住。

以下例子中,線程 A 鎖定 mutex1,線程 B 鎖定 mutex2,接著 A 和 B 分別嘗試鎖定對方已經(jīng)持有的互斥鎖,導(dǎo)致相互等待,程序進(jìn)入死鎖狀態(tài)。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;void *threadA(void *arg) {    pthread_mutex_lock(&mutex1);    sleep(1);  // 模擬工作    pthread_mutex_lock(&mutex2);  // 這里會發(fā)生死鎖    pthread_mutex_unlock(&mutex2);    pthread_mutex_unlock(&mutex1);    return NULL;}void *threadB(void *arg) {    pthread_mutex_lock(&mutex2);    sleep(1);  // 模擬工作    pthread_mutex_lock(&mutex1);  // 這里會發(fā)生死鎖    pthread_mutex_unlock(&mutex1);    pthread_mutex_unlock(&mutex2);    return NULL;}

預(yù)防死鎖方法:

固定鎖順序:所有線程在請求多個鎖時,必須按照相同的順序來請求。超時加鎖:使用 pthread_mutex_trylock(),可以避免線程長時間等待鎖。

6、互斥鎖的屬性

pthread_mutexattr_t 結(jié)構(gòu)體用于控制互斥鎖的行為。常用屬性包括互斥鎖的類型。

通過 pthread_mutexattr_settype() 設(shè)置互斥鎖的類型。

常見類型包括:

PTHREAD_MUTEX_NORMAL:普通互斥鎖,不會檢查錯誤,遞歸加鎖會導(dǎo)致死鎖。PTHREAD_MUTEX_ERRORCHECK:錯誤檢查互斥鎖,如果同一線程重復(fù)加鎖,返回 EDEADLK 錯誤。PTHREAD_MUTEX_RECURSIVE:遞歸鎖,允許同一線程對互斥鎖多次加鎖,但需要相同次數(shù)的解鎖。PTHREAD_MUTEX_DEFAULT:默認(rèn)行為,通常與 PTHREAD_MUTEX_NORMAL 等價。

設(shè)置遞歸鎖的示例:

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

pthread_mutex_t mutex;pthread_mutexattr_t attr;pthread_mutexattr_init(&attr);  // 初始化屬性pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);  // 設(shè)置遞歸鎖類型pthread_mutex_init(&mutex, &attr);  // 初始化互斥鎖pthread_mutexattr_destroy(&attr);  // 銷毀屬性

返回值:

0:成功。EINVAL:互斥鎖屬性無效。

互斥鎖的正確使用包括初始化、加鎖、解鎖和銷毀。

通過靜態(tài)或動態(tài)方法初始化互斥鎖,根據(jù)需求選擇合適的鎖類型,可以有效避免線程競爭和死鎖問題。

相關(guān)閱讀

主站蜘蛛池模板: 一级久久久久久 | 日韩和的一区二在线 | 日本 欧美 国产 | 天堂av免费观看 | 久久久精品影院 | 9久9久9久女女女九九九一九 | 国产精品不卡 | 在线免费观看成人 | 在线综合视频 | 欧美男人亚洲天堂 | 亚洲 欧美 精品 | 精品久久久一区 | 中文字幕乱码一区二区三区 | 欧美一区二区三区四区视频 | 国产农村妇女精品一二区 | 在线天堂免费中文字幕视频 | 欧美在线小视频 | 免费观看的av | 一级黄色片网站 | 91精品国产91久久久久久 | 国产日韩欧美激情 | 亚洲国产一区二区视频 | 欧美一级在线观看 | 国产日韩一区二区 | 日本欧美国产在线 | 日韩电影一区二区三区 | 一区精品国产欧美在线 | 在线免费观看成人 | 精品欧美乱码久久久久久 | 日韩中文字幕2019 | 欧美福利| 91精品国产综合久久久久蜜臀 | www.日韩在线 | 日韩精品久久一区二区三区 | 成人欧美一区二区三区在线播放 | 欧美日韩精品久久久免费观看 | 成人免费小视频 | 国产精品成人一区二区三区夜夜夜 | 国产丝袜一区二区三区免费视频 | 精品国产一二三区 | 日韩精品在线免费观看视频 |