读写锁(rwlock、pthread_cancel、pthread_cleanup_push、pthread_cleanup_pop)

读写锁

原因:

  基于效率,用于共享内存 

原理:

1、多个线程可以同时用于读操作;单个线程只能用于写操作
2、当cpu资源释放后,存在读锁、和写锁时,一般根据系统不同,读锁和写锁的优先级不一样
3、读优先时,只有写时才会被阻塞 if(rw->rw_refcount<0)
4、写优先时,正在读或者写等待时会阻塞if((rw->rw->refconut>0)||rw->nwaitwriters>0)

函数

pthread_rwlock_t  rwlock;//类型
pthread_rwlock_rdlock();//读锁
pthread_rwlock_wrlock();//写锁
phread_rwlock_unlock();//解锁
 2 #include<unistd.h>
  3 #include<pthread.h>
  4 pthread_rwlock_t rwlock;
  5 void *Fun1(void* arg)
  6 {
  7     //pthread_rwlock_wrlock(&rwlock);
        //加读锁,未解锁
  8     pthread_rwlock_rdlock(&rwlock);
  9     printf("This is Fun1 pthread.\n");
 10 }
 11 void *Fun2(void* arg)
 12 {
         //加读锁,未解锁
 13     pthread_rwlock_rdlock(&rwlock);
 14     printf("This is Fun2 pthread.\n");
 15 }
 16 int main()
 17 {
 18     pthread_t tid1,tid2;
 19     pthread_create(&tid1,NULL,Fun1,NULL);
 20     sleep(1);
 21     pthread_create(&tid2,NULL,Fun2,NULL);
 22     pthread_join(tid1,NULL);
 23     pthread_join(tid2,NULL);
 24     return 0;
 25 }

解释

1、线程函数Fun1、Fun2,都用于读时,不会发生阻塞 2、线程Fun1,用于读操作,Fun2用于写时,会发生死锁;写操作没有机会执行

锁机制和互斥量(二值互斥量)

锁机制:小于0 用于写 等于0 不操作 大于零 读操作

互斥量:小于零阻塞 大于0 运行

线程取消

1、利用线程可以取消正在执行的线程,造成了该线程持有资源死亡,会导致未执行的线程出现死锁

cleanup

pthread_cleanup_push();//对死锁问题进行处理,即恢复现场
pthread_cleanup_pop();

这对函数会解决以下问题:

1、调用线程被取消(pthread_cnacel());
2、调用线程结束函数自愿结束(pthread_exit())
3、pthread_cleanup_pop(int execute);//execute 不为0

过程

利用信号量和条件变量可以实现读写锁机制

//my_pthread_rwlock.h
  1 #ifndef __MY_PTHREAD_RWLOCK_H__
  2 #define __MY_PTHREAD_RWLOCK_H__
  3 #include<stdio.h>
  4 #include<unistd.h>
  5 #include<pthread.h>
  6 typedef struct
  7 {
  8     pthread_mutex_t rw_mutex;
  9     pthread_cond_t rw_condreaders;
 10     pthread_cond_t rw_condwriters;
 11     int rw_magic;
 12     int rw_nwaitwriters;
 13     int rw_nwaitreaders;
 14     int rw_refcount;// -1 wr   0    >0 rd
 15 }my_pthread_rwlock_t ;
 16 //校验码
 17 #define RW_MAGIC 0x12345678
   //初始化
 18 #define PTHREAD_RWLOCK_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,    \
 19 PTHREAD_COND_INITIALIZER,\
 20 PTHREAD_COND_INITIALIZER,\
 21 RW_MAGIC, 0,0,0}
     //读锁
 22 int my_pthread_rwlock_rdlock(my_pthread_rwlock_t *rw);
 23 //写锁
    int my_pthread_rwlock_wrlock(my_pthread_rwlock_t *rd);
 24 //解锁 
 int my_pthread_rwlock_unlock(my_pthread_rwlock_t *lc);
 25 #endif
//achieve.h
 #include"my_pthread_rwlock.h"
  2 enum{ EINVAL =1};
     //rdlock
 3 my_pthread_rwlock_rdlock(my_pthread_rwlock_t *rw)
  4 {
  5     int result;
      //校验
  6     if(rw->rw_magic != RW_MAGIC)
  7         return EINVAL;
  8     //加锁失败
  9     if((result = pthread_mutex_lock(&rw->rw_mutex ))!=0)
 10         return result;
 11     //有线程正在写 有线程等待写; //写优先
 12     while(rw->rw_refcount<0||rw->rw_nwaitwriters>0)
 13     {
 14         rw->rw_nwaitreaders++;
         //读阻塞   
             result = pthread_cond_wait(&rw->rw_condreaders,&rw->rw_mutex);
 16         rw->rw_nwaitreaders--;
 17         if(result != 0)
 18             break;
 19     }
 20     if(result == 0)
 21     {
 22         rw->rw_refcount++;
 23     }
 26 }
 27 //rwlock
 28 my_pthread_rwlock_wrlock(my_pthread_rwlock_t *rw)
 29 {
 30     int result;
 31     if(rw->rw_magic != RW_MAGIC)
 32         return EINVAL;
 33     if((result = pthread_mutex_lock(&rw->rw_mutex))!=0)
 34         return result;
         //wrlock   没有读、没有写 用于写
 35     while(rw->rw_refcount !=0)
 36     {
 37         rw->rw_nwaitwriters++;
         pthread_cond_wait(rw->nwaitwriters ,&rw->mutex);
 39         rw->rw_nwaitwriters--; 
 40         if(result != 0)
 41            break;
        }
 42
 43     if(result == 0)
 44         rw->rw_refcount = -1;
 45     pthread_mutex_unlock(&rw->rw_mutex);
 46     return result;
 47 }
 48 //解锁
 49 my_pthread_rwlock_unlock(my_pthread_rwlock_t *rw)
 50 {
 51     int result;
 52     if(rw->rw_magic != RW_MAGIC)
 53         return EINVAL;
 54     if((result = pthread_mutex_lock(&rw->rw_mutex))!=0)
 55         return result;
         //读锁
 56     if(rw->rw_refcount>0)
 57     {
 58         rw->rw_refcount--;
 59     }
         //写锁
 60     else if(rw->rw_refcount == -1)
 61     {
 62         rw->rw_refcount = 0;
 63     }
 64     else
 65     {
 66         printf("unlock wrlock fail\n");
 67     }
         //唤醒写锁
 68     if(rw->rw_nwaitwriters>0)
 69     {
 70         if(rw->rw_refcount == 0)
 71             result = pthread_cond_signal(&rw->rw_condwriters);
 72     }
         //唤醒读锁
 73     else if(rw->rw_nwaitreaders>0)
 74     {
 75         result =pthread_cond_broadcast(&rw->rw_condreaders);
 76     }
 77     pthread_mutex_unlock(&rw->rw_mutex);
 78     return result;
 79 }

[详细代码点击me https://github.com/wdhani82475/Project.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值