读写锁状态
1.读模式下加锁状态(读锁)
2.写模式下加锁状态(写锁)
3.不加锁状态
读写锁特性
1.读写锁是“写模式加锁”时,解锁前,所有对该锁加锁的线程都会被阻塞。
2.读写锁是“读模式加锁”时,如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。
3.读写锁是“读模式加锁”时,既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁会阻塞随后的读模式锁请求。优先满足写模式锁。读锁、写锁并行阻塞,写锁优先级高。
读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。写独占、读共享。
读写锁非常适合于对数据结构读的次数远大于写的情况
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<pthread.h>
int count; //全局变量,多个线程共享
pthread_rwlock_t rwlock;//读写锁
void *th_write(void* arg)
{
int t;
int i=(int)arg;
while(1)
{
t=count;
usleep(1000);
pthread_rwlock_wrlock(&rwlock);//写锁,count++操作
printf("write %d: %lu : count=%d ++count=%d\n",i,pthread_self(),t,++count);
usleep(2000);//未解锁期间,count不能被其它线程读和写加锁
pthread_rwlock_unlock(&rwlock);
//解锁后如果有多个线程加锁请求,优先响应写锁请求
printf("write %d unlock\n",i);
usleep(5000);
}
return NULL;
}
void *th_read(void *arg)
{
int i=(int)arg;
while(1)
{
pthread_rwlock_rdlock(&rwlock);//读加锁
printf("-------------read %d, %lu: %d\n",i,pthread_self(),count);
usleep(2000);//未解锁期间,count可以被其它线程读模式加锁访问
pthread_rwlock_unlock(&rwlock);//解锁后可以被写模式加锁修改
printf("--------------read %d unlock\n",i);
usleep(900);
}
return NULL;
}
int main()
{
int i;
pthread_t tid[8];
pthread_rwlock_init(&rwlock,NULL);// 初始化读写锁
for(i=0;i<3;i++)
pthread_create(&tid[i],NULL,th_write,(void*)i);//读线程
for(i=0;i<5;i++)
pthread_create(&tid[i+3],NULL,th_read,(void*)i);//写线程
for(i=0;i<8;i++)
pthread_join(tid[i],NULL);//回收线程
pthread_rwlock_destroy(&rwlock);//回收读写锁
return 0;
}
结果如下:可以发现
1.读模式加锁时,不用等待解锁,5个读函数线程可以共享全局变量count
2.读模式加锁时,写模式加锁处于阻塞等待状态,等所有读模式锁被解锁后才可以用写模式加锁。(read聚在一起排列)
3.写模式加锁时,一定会等到解锁时才能执行下一个写模式加锁,不会同时共享全局变量count
4.写模式解锁时,优先响应写模式加锁请求。(write聚在一起排列)。