C實現讀寫鎖


一、概述

  案例:編寫一個案例測試讀寫鎖,要求:新建三個線程寫,5個線程讀,來測試讀寫鎖。

  讀寫鎖的基本概念:

      讀寫鎖也叫共享-獨占鎖。當讀寫鎖以讀模式鎖住時,它是以共享模式鎖住的;當它以寫模式鎖住時,它是以獨占模式鎖住的。寫獨占,讀共享

  讀寫鎖的使用場合:

      對數據結構讀的次數遠大於寫的情況

  讀寫鎖的特性:

      1.讀寫鎖是“寫模式加鎖”時,解鎖前,所有對該鎖加鎖的線程都會被阻塞

      2.讀寫鎖是“讀模式加鎖”時,如果線程以讀模式對其加鎖會成功;如果線程以寫模式加鎖會阻塞。

      3.讀寫鎖是“讀模式加鎖”時, 既有試圖以寫模式加鎖的線程,也有試圖以讀模式加鎖的線程。那么讀寫鎖會阻塞隨后的讀模式鎖請求。優先滿足寫模式鎖。讀鎖、寫鎖並行阻塞,寫鎖優先級高

  

  讀寫鎖場景練習:

    1. 線程A加寫鎖成功, 線程B請求讀鎖

    答:線程B阻塞

    2.線程A持有讀鎖, 線程B請求寫鎖

    答:線程B阻塞

    3.線程A擁有讀鎖, 線程B請求讀鎖

    答:線程B加鎖成功

    4.線程A持有讀鎖, 然后線程B請求寫鎖, 然后線程C請求讀鎖

    答:B阻塞,c阻塞 - 寫的優先級高

    5.A解鎖,B線程加寫鎖成功,C繼續阻塞

    答:B解鎖,C加讀鎖成功

    6.線程A持有寫鎖, 然后線程B請求讀鎖, 然后線程C請求寫鎖

    答:BC阻塞

    7.A解鎖,C加寫鎖成功,B繼續阻塞

    答:C解鎖,B加讀鎖成功

  讀寫鎖操作的基本步驟:

    1.定義一把鎖:pthread_rwlock_t rwlock;

    2.初始化讀寫鎖:pthread_rwlock_init()

    3.加讀鎖:pthread_rwlock_rdlock()

    4.加寫鎖:pthread_rwlock_wrlock()

    5.解鎖:pthread_rwlock_unlock();

    6.釋放鎖:pthread_rwlock_destroy();

 

  根據以上6步驟,下面看看具體的代碼示例

二、代碼示例

//讀寫鎖測試程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

//定義一個全局變量
int number = 0;
//定義一把讀寫鎖
pthread_rwlock_t rwlock;


//寫線程回調函數
void * thread_write(void *arg){
        int i = *(int *)arg;
        int cur;
        while(1){
                //加寫鎖
                pthread_rwlock_wrlock(&rwlock);
                cur = number;
                cur++;
                number = cur;
                printf("[%d]-W:[%d]\n",i,cur);
                //解鎖
                pthread_rwlock_unlock(&rwlock);
                sleep(rand()%3);
        }
}

//讀線程回調函數
void *thread_read(void *arg){
        int i = *(int *)arg;
        int cur;
        while(1){
                //加讀鎖
                pthread_rwlock_rdlock(&rwlock);
                cur = number;
                printf("[%d]-R:[%d]\n",i,cur);
//讀寫鎖測試程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

//定義一個全局變量
int number = 0;
//定義一把讀寫鎖
pthread_rwlock_t rwlock;


//寫線程回調函數
void * thread_write(void *arg){
        int i = *(int *)arg;
        int cur;
        while(1){
                //加寫鎖
                pthread_rwlock_wrlock(&rwlock);
                cur = number;
                cur++;
                number = cur;
                printf("[%d]-W:[%d]\n",i,cur);
                //解鎖
                pthread_rwlock_unlock(&rwlock);
                sleep(rand()%3);
        }
}

//讀線程回調函數
void *thread_read(void *arg){
        int i = *(int *)arg;
        int cur;
        while(1){
                //加讀鎖
                pthread_rwlock_rdlock(&rwlock);
                cur = number;
                printf("[%d]-R:[%d]\n",i,cur);
                //解鎖
                pthread_rwlock_unlock(&rwlock);
                sleep(rand()%3);
        }

}

int main(){
        int n = 8;
        int i =0;
        int arr[8];
        //定義線程 id
        pthread_t thread[8];
        //初始化讀寫鎖
        pthread_rwlock_init(&rwlock,NULL);
        //創建是哪個寫鎖
        for(i=0;i<3;i++){
                arr[i] = i;
                //創建寫線程
                pthread_create(&thread[i],NULL,thread_write,&arr[i]);
        }
        //創建5個讀線程
        for(i=3;i<n;i++){
                arr[i] = i;
                //創建讀線程
                pthread_create(&thread[i],NULL,thread_read,&arr[i]);
        }
        //回收子線程
        int j = 0;
        for(j=0;j<n;j++){
                pthread_join(thread[j],NULL);
        }
        //釋放鎖
        pthread_rwlock_destroy(&rwlock);
        return 0;
}
    

 

三、示例圖

  如下圖所示:讀出來的數據永遠是寫入的最后一個數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM