久综合色-久综合网-玖草影视-玖草资源在线-亚洲黄色片子-亚洲黄色片在线观看

Hello! 歡迎來到小浪云!


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


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

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

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

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

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

互斥鎖的工作原理:

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

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

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

1、互斥鎖的初始化

互斥鎖在使用之前必須先進行初始化操作。

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

1.1、靜態初始化

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

無需顯式調用初始化函數,適用于全局互斥鎖。

代碼語言:JavaScript代碼運行次數:0運行復制

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

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

1.2、動態初始化

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

代碼語言:javascript代碼運行次數:0運行復制

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

參數:

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

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

EINVAL:attr 屬性無效。EBUSY:互斥鎖已經被初始化。ENOMEM:內存不足,無法分配資源。

2、互斥鎖加鎖與解鎖

2.1、互斥鎖加鎖

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

如果互斥鎖已經被其他線程鎖住,調用線程將進入阻塞狀態,直到該互斥鎖被解鎖。

代碼語言:javascript代碼運行次數:0運行復制

pthread_mutex_lock(&mutex);  // 加鎖

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

返回值:成功時返回 0。如果出現錯誤,返回非零錯誤碼:

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

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

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

代碼語言:javascript代碼運行次數:0運行復制

pthread_mutex_unlock(&mutex);  // 解鎖

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

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

EINVAL:互斥鎖無效。EPERM:當前線程沒有持有該互斥鎖。

3、非阻塞加鎖

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

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

代碼語言:javascript代碼運行次數:0運行復制

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("嘗試鎖定時出現錯誤。n");    }    return 0;}

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

返回值:

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

4、銷毀互斥鎖

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

銷毀互斥鎖之前,確保它已經被解鎖。

代碼語言:javascript代碼運行次數:0運行復制

pthread_mutex_destroy(&mutex);

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

返回值:

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

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

5、互斥鎖死鎖問題

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

以下例子中,線程 A 鎖定 mutex1,線程 B 鎖定 mutex2,接著 A 和 B 分別嘗試鎖定對方已經持有的互斥鎖,導致相互等待,程序進入死鎖狀態。

代碼語言:javascript代碼運行次數:0運行復制

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);  // 這里會發生死鎖    pthread_mutex_unlock(&mutex2);    pthread_mutex_unlock(&mutex1);    return NULL;}void *threadB(void *arg) {    pthread_mutex_lock(&mutex2);    sleep(1);  // 模擬工作    pthread_mutex_lock(&mutex1);  // 這里會發生死鎖    pthread_mutex_unlock(&mutex1);    pthread_mutex_unlock(&mutex2);    return NULL;}

預防死鎖方法:

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

6、互斥鎖的屬性

pthread_mutexattr_t 結構體用于控制互斥鎖的行為。常用屬性包括互斥鎖的類型。

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

常見類型包括:

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

設置遞歸鎖的示例:

代碼語言:javascript代碼運行次數:0運行復制

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

返回值:

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

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

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

相關閱讀

主站蜘蛛池模板: 99视频久久 | 亚洲不卡影院 | 久久永久免费视频 | 免费看黄网 | 黄免费看 | 美女图片1314mm爽爽爽 | 国产精品自拍视频 | 欧美一级一极性活片免费观看 | 91香蕉视 | 亚洲精美视频 | 日本久久精品视频 | 久久黄色免费网站 | 久久在线一区 | 久久久影院亚洲精品 | 免费一级夫妻a | 男女男精品视频免费观看 | 久操免费在线视频 | 美女毛片免费看 | 欧美一级毛片一级 | 92看片淫黄大片看国产片 | 日韩在线三级 | 粉嫩jk制服美女啪啪 | 国产一区二区三区免费在线观看 | 欧美三区在线 | 成年女人免费视频播放成年m | 美女黄网站色一级毛片 | 亚洲视频在线观看网站 | 国产欧美精品区一区二区三区 | 在线精品国产 | 波多野结衣被强在线视频 | 美女的让男人桶到爽软件 | 日韩黄色片在线观看 | 欧美黄区 | 国产国产人免费视频成69堂 | 久久精品综合 | 神马三级我不卡 | 男人女人做性全程视视频 | 美女被拍拍拍拍拍拍拍拍 | 亚洲精品综合 | 亚洲日韩中文字幕在线播放 | 欧美巨大精品videos |