1.读写锁是几把锁?
一把锁
pthread_rwlock_t lock;
2.读写锁的类型;
读锁-对内存做读操作
写锁-对内存做写操作
3.读写锁的状态

4.读写锁的特性:
线程A加读锁成功,又来了三个线程,做读操作,可以加锁成功
读共享-并行处理
线程A加写锁成功,又来了三个线程,做读操作,三个线程阻塞
写独占
线程A加读锁成功,又来了B线程加写锁阻塞,又来了C线程加读锁阻塞
读写不可以同时进行
写的优先级高
5.读写锁场景练习
线程A加写锁成功,线程B请求读锁
线程B阻塞
线程A持有读锁,线程B请求写锁
线程B阻塞
线程A拥有读锁,线程B请求读锁
线程B加锁
线程A持有读锁,然后线程B请求写锁,然后线程C请求读锁
线程B阻塞,线程C阻塞
线程B加锁,线程C阻塞
线程C加锁
线程A持有写锁,然后线程B请求读锁,然后线程C请求写锁
线程B阻塞,线程C阻塞
线程C加锁, 线程B阻塞
线程B加锁
6.读写锁的适用场景
互斥锁-读写串行
读写锁:
读:并行 写:串行
程序中的读操作 > 写操作的时候
7.主要操作函数
初始化读写锁
pthread_rwlock_init(pthread_rwlock_t* restrict rwlock, const pthread_rwlockattr_t* restrict attr ); 销毁读写锁
pthread_rwlock_destroy(pthread_rwlock_t* rwlock):
加读锁
pthread_rwlock_rdlock(pthread_rwlock_t* rdlock);
阻塞:之前对这把锁加的是写锁的操作
尝试加读锁
pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock);
加锁成功:返回0 失败:返回错误号
加写锁
pthread_rwlock_wrlock(pthread_rwlock_t* rwlock);
阻塞:上一次加写锁还没解锁 阻塞:上一次加读锁还没解锁
尝试加写锁
pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock);
解锁
pthread_rwlock_unlock(pthread_rwlock_t* rwlock);
8.练习
三个线程不定时写同一个全局变量,五个线程不定时期读同一全局资源 先不加锁
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
int number = 0;
void* write_func(void *arg)
{
while(1)
{
number++;
printf("write:%ld,%d\n",pthread_self(),number);
usleep(500);
}
}
void* read_func(void *arg)
{
while(1)
{
printf("read:%ld,%d\n",pthread_self(),number);
usleep(500);
}
}
int main()
{
pthread_t p[8];
for(int i=0;i<3;++i)
{
pthread_create(&p[i],NULL,write_func,NULL);
}
for(int i=3;i<8;++i)
{
pthread_create(&p[i],NULL,read_func,NULL);
}
for(int i=0;i<8;++i)
{
pthread_join(p[i],NULL);
}
return 0;
}

这段代码的问题:
-
3 个写线程 + 5 个读线程同时访问 number
-
number++ 不是原子操作
-
读和写同时发生,会出现脏数据、重复数据、错乱数据
-
没有任何同步控制,线程自由竞争,数据不安全
现象:
-
写线程在改
-
读线程在读
-
输出会乱、数字会跳、重复、甚至读到一半的值
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>int number = 0;
//create rwlock
pthread_rwlock_t lock;void* write_func(void arg)
{
while(1)
{
pthread_rwlock_wrlock(&lock);
number++;
printf("write:%ld,%d\n",pthread_self(),number);
pthread_rwlock_unlock(&lock);
usleep(500);
}
}
void read_func(void *arg)
{
while(1)
{
pthread_rwlock_rdlock(&lock);
printf("read:%ld,%d\n",pthread_self(),number);
pthread_rwlock_unlock(&lock);
usleep(500);
}
}
int main()
{
pthread_rwlock_init(&lock,NULL);
pthread_t p[8];for(int i=0;i<3;++i) { pthread_create(&p[i],NULL,write_func,NULL); } for(int i=3;i<8;++i) { pthread_create(&p[i],NULL,read_func,NULL); } for(int i=0;i<8;++i) { pthread_join(p[i],NULL); } pthread_rwlock_destroy(&lock); return 0;}

加了读写锁之后,就没有出现数据混乱的现象
读写锁版本
严格遵守 3 条黄金规则:
规则 1:写锁 == 独占锁
同一时间只能有一个写线程加锁
规则 2:读锁 == 共享锁
多个读线程可以同时加锁(5 个读线程可以一起读)
规则 3:写与读互斥
-
有写锁,读锁必须等待
-
有读锁,写锁必须等待