读写锁
(1)与互斥量类似,但是读写锁允许更高的并行性。其特点为:
写优先
写独占,读共享
(2)使用场景:读写锁非常适合于对数据结构读的次数远大于写的情况
(3)读写锁有3种状态:加读锁、加写锁、不加锁
读写锁的特性
- 读写锁是“加写锁”时:在解锁之前,所有对该锁加锁的线程都会被阻塞
- 读写锁是“加读锁”时:如果线程再申请加读锁就会成功;如果线程再申请加写锁就会阻塞
- 读写锁是“加读锁”时,既有试图加写锁的线程,又有试图加读锁的线程:那么读写锁会阻塞随后的读锁请求。优先满足写锁请求。读锁、写锁并行阻塞,写锁优先级高
读写锁API
pthread_rdlock_t lock;//读写锁类型
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_trywrlock(pthread_rwlock_t *rwlock); //加[写锁]
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); //尝试加[写锁]
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); //解锁
示例代码
程序功能:3个线程不定时[写]同一个全局资源number,5个线程不定时[读]同一个全局资源number
int number=0; // 全局资源
pthread_rwlock_t lock; //因为只有一个资源,因此只需要一个rdlock
void* write_func(void* arg){
while(1){
pthread_rwlock_wrlock(&lock); //加[写]锁
number++;
printf("====%dth thread %lu write: %d\n",(int)arg,pthread_self(),number);
pthread_rwlock_unlock(&lock);
usleep(500);
}
return NULL;
}
void* read_func(void* arg){
while(1){
pthread_rwlock_rdlock(&lock); //加[读]锁
printf(" %dth thread %lu read: %d\n",(int)arg,pthread_self(),number);
pthread_rwlock_unlock(&lock);
usleep(500);
}
return NULL;
}
int main(){
pthread_rwlock_init(&lock,NULL);
pthread_t tid[8];
//创建3个写线程
for(int i=0;i<3;i++){
pthread_create(&tid[i],NULL,write_func,(void*)i);
}
//创建5个读线程
for(int i=3;i<8;i++){
pthread_create(&tid[i],NULL,read_func,(void*)i);
}
for(int i=0;i<8;i++)
pthread_join(tid[i],NULL);
pthread_rwlock_destroy(&lock);
return 0;
}
程序执行结果:从上到下,数字肯定是递增的。