一.读写锁
与前面介绍的互斥锁类似,但读写锁有更高的并行性。
二.读写锁的状态
1.读锁【读模式下的锁】
2.写锁【写模式下的锁】
3.不加锁
三.读写锁的特点
- 1.读写锁是“写模式加锁”时,解锁前,所有对该锁加锁的线程都会被阻塞。
- 2.读写锁是“读模式加锁”时,如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。
- 3.读写锁是“读模式加锁”时,既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁
会阻塞随后的读模式锁请求。优先满足写模式锁。读锁、写锁并行阻塞,写锁优先级高读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的。读写锁非常适合于对数据结构读的次数远大于写的情况。
四.主要应用函数
pthread_rwlock init,函数
pthread_rwlock_destroy函数
pthread_rwlock_rdlock函数
pthread_rwlock_wrlock,函数
pthread_rwlock_tryrdlock,函数
pthread_rwlock_trywrlock函数
pthread_rwlock_unlock函数
以上7个函数的返回值都是:成功返回0,失败直接返回错误号。
pthread_rwlock_t类型用子定义一个读写锁变量。
pthread_rwlock_t rwlock;
五.读写锁的原理
六.代码Demo
#include <iostream>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
using namespace std;
#define THREAD_NUM 8
pthread_rwlock_t rwlock;
int n=0;
void*
thread_func_read(void* arg)
{
int *index = (int*)arg;
int i=4;
while(i--){
pthread_rwlock_rdlock(&rwlock);
printf("I am the %dth son thread ID:%lu \n", *index, pthread_self());
printf("the value of n is %d \n", n); // 对n读模式
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
delete index;
}
void*
thread_func_write(void* arg)
{
int *index = (int*)arg;
int i=4;
while(i--){
pthread_rwlock_wrlock(&rwlock);
printf("I am the %dth son thread ID:%lu \n", *index, pthread_self());
n++; // 写模式
printf("the value of n is %d \n", n);
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
delete index;
}
int
main(int argc, char*argv[])
{
pthread_t tid[THREAD_NUM];
pthread_attr_t attr;
int err, i, *value;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_rwlock_init(&rwlock, NULL);
for(i=0; i<THREAD_NUM/2; i++){
value = new int(i+1);
if( (err = pthread_create(&tid[i], &attr, thread_func_read, (void*)value)) != 0){
fprintf(stderr, "%dth thread create error the reason is %s \n", *value, strerror(err));
delete value;
}
}
for( ; i<THREAD_NUM; i++){
value = new int(i+1);
if( (err = pthread_create(&tid[i], &attr, thread_func_write, (void*)value)) != 0){
fprintf(stderr, "%dth thread create error the reason is %s \n", *value, strerror(err));
delete value;
}
}
for(i=0; i<THREAD_NUM; i++){
pthread_join(tid[i], NULL);
}
pthread_attr_destroy(&attr);
pthread_rwlock_destroy(&rwlock);
pthread_exit(NULL);
}