读写锁
原因:
基于效率,用于共享内存
原理:
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 }