读写锁
读写锁是一把锁
读写锁的类型
锁读操作
锁写操作
不加锁
读写锁的特性
1、线程A加读锁成功, 又来了三个线程, 做读操作, 可以加锁成功-------》加读锁, 可以并行
2、线程A加写锁成功, 又来了三个线程, 做读操作, 三个线程阻塞-------》写操作的时候不能读, 写的时候是串行的
3、线程A加读锁成功, 又来了B线程加写锁阻塞, 又来了C线程加读锁阻塞-------》写的优先级高
4、读共享, 写独占, 写的优先级高
读写锁场景
1、线程A加写锁成功, 线程B请求读锁-----》线程b阻塞
2、线程A持有读锁, 线程B请求写锁-------》线程B阻塞
3、线程A拥有读锁, 线程B请求读锁-------》线程B加锁成功
4、线程A持有读锁, 然后线程B请求写锁, 然后线程C请求读锁-------》BC阻塞;A解锁B加锁成功,C阻塞;B解锁C加锁成功
5、线程A持有写锁, 然后线程B请求读锁, 然后线程C请求写锁-------》BC阻塞;A解锁, C加锁成功, B阻塞;C解锁, B加锁
读写锁的适用场景
读 - 并行
写 - 串行
读的操作>写操作的
操作函数
初始化读写锁
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 *rwlock);
尝试加读锁
pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
加写锁
pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
尝试加写锁
pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
解锁
pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
测试
3个线程不定时写同一全局资源,5个线程不定时读同一全局资源
测试源码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
// 全局变量
int number;
pthread_rwlock_t rwlock;
void* write_func(void* arg)
{
while(1)
{
pthread_rwlock_wrlock(&rwlock);
number++;
printf("[%lu]+++ write number: %d\n",pthread_self(), number);
pthread_rwlock_unlock(&rwlock);
usleep(1000);
}
return NULL;
}
void* read_func(void* arg)
{
while(1)
{
pthread_rwlock_rdlock(&rwlock);
printf("[%lu]--- read number: %d\n",pthread_self(), number);
pthread_rwlock_unlock(&rwlock);
usleep(500);
}
return NULL;
}
int main(int argc, const char* argv[])
{
pthread_t thid[8];
pthread_rwlock_init(&rwlock, NULL);
// 创建线程
for(int i=0; i<3; ++i)
{
pthread_create(&thid[i], NULL, write_func, NULL);
}
for(int i=3; i<8; ++i)
{
pthread_create(&thid[i], NULL, read_func, NULL);
}
// 回收
for(int i=0; i<8; ++i)
{
pthread_join(thid[i], NULL);
}
pthread_rwlock_destroy(&rwlock);
return 0;
}