概述
概述
读写锁类似于互斥锁(互斥量),不过读写锁允许更高的并行性,主要体现在读者方面。这种锁有利于读的机会多,写的机会少的共享数据。它可分为以下两种情况:
- 写者竞争到锁资源。在写者加锁,正在写的情况下,所有试图竞争这个锁的读者写者线程都会被阻塞。
- 读者竞争到锁资源。在读写加锁,正在读的情况下,为了体现并行性,当有新读者试图读取并且申请加锁的时候,将被允许。也就是说,一块共享数据可以同时被多个读者读取。但当有写者试图写时,将被阻塞。直到所有的读者线程释放锁为止。
但是,通常在读者占用锁资源的情况下(可能有一个读者,可能有多个读者),当一个写者请求锁资源,系统通常会阻塞随后的读者请求。这样做可以保证被读的资源充足。并且防止读者一直占用锁,而写者长时间得不到满足。
注意,共享数据这个概念是很重要的,读写锁也可以理解为就是用来保护这块共享数据的。
操作函数
与互斥锁相同,读写锁也有自己的类型:pthread_rwlock_t。
初始化方式
在创建互斥锁的时候有两种方式,①:定义一个全局变量pthread_rwlock_t。②利用malloc进行动态分配。切记不可定义成局部变量,读写锁是要被多个线程访问的,如果读写锁是被定义在一个线程内部的局部变量,当出了作用域被另一个线程访问时,这个锁就变成了无效的,还有可能引起无法预料的后果。
-利用宏PTNREAD_RWLOCK_INITIALIZER
定义一个全局变量,直接利用宏PTNREAD_RWLOCK_INITIALIZER进行初始化。
pthread_rwlock_t lock = PTNREAD_RWLOCK_INITIALIZER;
- 调用函数pthread_rwlock_init
定义一个局部的或者全局的读写锁,调用函数进行初始化。
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);
init函数有两个参数,第一个参数rwlock即为我们定义的读写锁,我们一般讲第二个参数attr指针设为null,代表互斥锁有默认属性。
摧毁
在利用完读写锁释放空间之前,需要调用pthread_rwlock_destroy做一些清理工作,释放锁资源 。init负责分配初始化锁资源,那必须就有destroy负责回收。如果还没有调用detroy进行释放锁资源,内存空间就被释放了,那么分配给这个锁的资源就会丢失。
#include<pthread.h>
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
加锁解锁
读写锁针对读者写者不同,设计了两种加锁函数。而解锁只有一种。
#include <pthread.h>
//读者加锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
//写者加锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
//解锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
这三个函数都是成功返回0,失败返回错误码。所以在每次申请锁资源时,都应检测是否申请成功。
除了上面两个函数外,还有以下两个尝试加锁函数。当申请不到锁资源时,线程就会被阻塞,而有些线程不希望这样。所以就可以调用尝试加锁,成功返回0,失败时直接返回错误EBUSY。
#include<pthread.h>
int pthread_rwlock_tyrrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
代码实例
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
pthread_rwlock_t lock; //定义读写锁
int data = 0;//定义共享数
//读者线程
void* thread_read(void* arg)
{
while(1)
{
sleep(1);
//读者申请锁,成功返回0,
if(pthread_rwlock_wrlock(&lock) == 0)
{
printf("Reader read a number: %dn",data);
pthread_rwlock_unlock(&lock);//解锁
}
else
{
printf("@n@n");
}
}
}
//写者线程
void* thread_write(void* arg)
{
while(1)
{
usleep(50000);
//写者申请锁,成功返回0.
if(pthread_rwlock_wrlock(&lock) == 0)
{
data++;
printf("Writer write a number: %dn",data);
pthread_rwlock_unlock(&lock);//解锁
}
else
{
printf("@n@n");
}
{
pthread_rwlock_init(&lock,NULL);//init函数初始化锁,分配锁资源
pthread_t reader;
pthread_t writer;
//创建读者线程
pthread_create(&reader,NULL,thread_read,NULL);
//创建写者线程
pthread_create(&writer,NULL,thread_write,NULL);
pthread_join(reader,NULL);
pthread_join(writer,NULL);
pthread_rwlock_destroy(&lock);//释放锁资源
return 0;
}
最后
以上就是复杂飞鸟为你收集整理的Linux多线程编程(四)-----读写锁的全部内容,希望文章能够帮你解决Linux多线程编程(四)-----读写锁所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复