随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

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;
}
    
复制代码

 

三、示例图

  如下图所示:读出来的数据永远是写入的最后一个数据。

 

posted on   飘杨......  阅读(1978)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示