日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C語言多線程開發中死鎖與讀寫鎖問題詳解_C 語言

作者:liufeng2023 ? 更新時間: 2022-06-28 編程語言

死鎖

有時,一個線程需要同時訪問兩個或更多不同的共享資源,而每個資源又都由不同的互斥量管理。當超過一個線程加鎖同一組互斥量時,就有可能發生死鎖;

兩個或兩個以上的進程在執行過程中,因爭奪共享資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖。

死鎖的幾種場景:

  • 忘記釋放鎖
  • 重復加鎖(重復加相同的鎖)
  • 多線程多鎖,搶占鎖資源

//多線程多鎖,搶占鎖資源
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 創建2個互斥量
pthread_mutex_t mutex1, mutex2;
void * workA(void * arg) {
    pthread_mutex_lock(&mutex1);
    sleep(1);
    pthread_mutex_lock(&mutex2);
    printf("workA....\n");
    pthread_mutex_unlock(&mutex2);
    pthread_mutex_unlock(&mutex1);
    return NULL;
}
void * workB(void * arg) {
    pthread_mutex_lock(&mutex2);
    sleep(1);
    pthread_mutex_lock(&mutex1);
    printf("workB....\n");
    pthread_mutex_unlock(&mutex1);
    pthread_mutex_unlock(&mutex2);
    return NULL;
}
int main() {
    // 初始化互斥量
    pthread_mutex_init(&mutex1, NULL);
    pthread_mutex_init(&mutex2, NULL);
    // 創建2個子線程
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, workA, NULL);
    pthread_create(&tid2, NULL, workB, NULL);
    // 回收子線程資源
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    // 釋放互斥量資源
    pthread_mutex_destroy(&mutex1);
    pthread_mutex_destroy(&mutex2);
    return 0;
}

執行結果:

讀寫鎖

/*
    讀寫鎖的類型 pthread_rwlock_t
    int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
    int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
    int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
    案例:8個線程操作同一個全局變量。
    3個線程不定時寫這個全局變量,5個線程不定時的讀這個全局變量
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 創建一個共享數據
int num = 1;
// pthread_mutex_t mutex;
pthread_rwlock_t rwlock;
void * writeNum(void * arg) {
    while(1) {
        pthread_rwlock_wrlock(&rwlock);
        num++;
        printf("++write, tid : %ld, num : %d\n", pthread_self(), num);
        pthread_rwlock_unlock(&rwlock);
        usleep(100);
    }
    return NULL;
}
void * readNum(void * arg) {
    while(1) {
        pthread_rwlock_rdlock(&rwlock); 
        printf("===read, tid : %ld, num : %d\n", pthread_self(), num);
        pthread_rwlock_unlock(&rwlock);
        usleep(100);
    }
    return NULL;
}
int main() {
   pthread_rwlock_init(&rwlock, NULL);
    // 創建3個寫線程,5個讀線程
    pthread_t wtids[3], rtids[5];
    for(int i = 0; i < 3; i++) {
        pthread_create(&wtids[i], NULL, writeNum, NULL);
    }
    for(int i = 0; i < 5; i++) {
        pthread_create(&rtids[i], NULL, readNum, NULL);
    }
    // 設置線程分離
    for(int i = 0; i < 3; i++) {
       pthread_detach(wtids[i]);
    }
    for(int i = 0; i < 5; i++) {
         pthread_detach(rtids[i]);
    }
    pthread_exit(NULL);
    pthread_rwlock_destroy(&rwlock);
    return 0;
}

執行結果:

讀時共享,相比互斥鎖,提高效率。

原文鏈接:https://blog.csdn.net/Edward_LF/article/details/124510241

欄目分類
最近更新