色偷偷91综合久久噜噜-色偷偷成人-色偷偷尼玛图亚洲综合-色偷偷人人澡久久天天-国内精品视频一区-国内精品视频一区二区三区

Hello! 歡迎來到小浪云!


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


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

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

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

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

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

互斥鎖的工作原理:

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

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

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

1、互斥鎖的初始化

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

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

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

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

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

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

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

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

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

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

pthread_mutex_t mutex;pthread_mutexattr_t attr;pthread_mutexattr_init(&attr);  // 初始化互斥鎖屬性// 初始化互斥鎖,第二個(gè)參數(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)屬性。

返回值:成功時(shí)返回 0,失敗時(shí)返回非零錯(cuò)誤碼。常見錯(cuò)誤碼包括:

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

2、互斥鎖加鎖與解鎖

2.1、互斥鎖加鎖

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

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

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

pthread_mutex_lock(&mutex);  // 加鎖

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

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

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

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

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

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

pthread_mutex_unlock(&mutex);  // 解鎖

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

返回值:成功時(shí)返回 0。可能的錯(cuò)誤碼:

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

3、非阻塞加鎖

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

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

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(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 {        // 其他錯(cuò)誤        printf("嘗試鎖定時(shí)出現(xiàn)錯(cuò)誤。n");    }    return 0;}

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

返回值:

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

4、銷毀互斥鎖

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

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

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

pthread_mutex_destroy(&mutex);

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

返回值:

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

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

5、互斥鎖死鎖問題

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

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

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(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);  // 這里會(huì)發(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);  // 這里會(huì)發(fā)生死鎖    pthread_mutex_unlock(&mutex1);    pthread_mutex_unlock(&mutex2);    return NULL;}

預(yù)防死鎖方法:

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

6、互斥鎖的屬性

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

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

常見類型包括:

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

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

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(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)或動(dòng)態(tài)方法初始化互斥鎖,根據(jù)需求選擇合適的鎖類型,可以有效避免線程競(jìng)爭(zhēng)和死鎖問題。

相關(guān)閱讀

主站蜘蛛池模板: 99九九| 人人揉人人爽五月天视频 | 男人天堂999 | 久久免费国产视频 | 香港三级在线视频 | 日日干视频 | 日本一区二区三区免费看 | 884hutv四虎永久黄网 | 三级黄色毛片视频 | 色博| 久久青草热 | 国产一级毛片国语版 | 国产精品久久vr专区 | 一级一片一a一片 | 精品福利视频一区二区三区 | 97国产精品欧美一区二区三区 | 秋霞免费理论片在线观看午夜 | 欧美一级淫片免费播放口 | 国产成人精品综合在线 | 色九九 | 国产精品一区久久精品 | 日韩精品一区二区三区不卡 | 伊人久久影院 | 黄色在线观看免费 | 欧美国产日韩911在线观看 | 欧美特黄三级在线观看 | 黄色的视频在线免费观看 | 丁香久久| 免费国产h视频在线观看 | 色爱区综合五月激情 | 亚洲一区日韩一区欧美一区a | 国产福利一区二区 | 国产激情一区二区三区四区 | 亚洲国产成人久久三区 | 四虎影视免费永久在线观看 | 四虎影在线永久免费观看 | 久久精品国产影库免费看 | 色综合久久88中文字幕 | aaa级毛片| 国产噜噜噜 | 黄色国产在线视频 |