多线程之读者写者模型
什么是读者写者问题?
为了能理解这个概念我们先举个列子:
我们在小时候,通常有一个东西叫做——黑板报!在一个班级上,有一个叫小明的学生,他字写的很高,有一天他正在画黑板报,同学们在他旁边看,窃窃私语的猜他在画什么东西!
有的猜说画的是蛇,有的说画的是龙,等等但是到最后其实画的是一个绳子——当小明正在出黑板报的时候!其他人读取到的只是内容的局部性的东西!最终读取的数据都是不正确的!只拿了一部分!
为了保证每一位学生读取到的数据是完整的,于是班级里面做了一个规定,在小明画完之前,大家都不能看!——小明要么就不出,要么就出完
小明将黑板报出完了之后!班级上的同学一个个的都围过来看!愉快的进行讨论!,那么讨论的时候,会不会说一个个都排好队,分别来看?或者会不会说我先来的!你们都闭上眼是我先来看?——肯定是不会的!都是一起看的!
但是出黑板报的时候!会不会有一个同学正在一个地方画,另一个同学说同时也想要在一个地方画的情况出现呢?——不会!肯定是一个个的来画
==对于读者写者问题,有三种关系!两种角色!一种交易场所!==
一个交易场所就是——黑板报,是一份共享资源!
两种关系就是指——读者与写者
-
对于出黑板的小明和其他出黑板报的人——就是典型的写者!
-
对于看黑板报的其他同学——就是典型的读者
==出黑板班的过程!其实本质就是一个读者写者问题!==
是三种关系:
- 写者和写者是什么关系?——小明和其他出黑板报的人是什么关系?是互斥关系总不能出现我要画画,它要写字,在同一个地方搞,我刚刚画完,另一个人就擦了写字!或者说反过来!==所以写者和写者之间是典型的互斥关系!==
- 读者和写者之间是什么关系?——我们上面说过!如果正在出黑板报的时候!其他同学来读取!那么就可能读取到的是残缺的数据!为了让读者能够读取到完整的数据!我们一定要保证!写者要么不写!要么写完后才能被允许读!==所以读者和写者之间就也是互斥关系!==(写的时候不要读!)
读写锁及其相关接口
在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。
给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢?有,那就是读写锁。——用于解决读者写者问题!
读写锁的原理
==系统是如何让同一个锁来实现两种不同的加锁行为的呢?==
pthread_rwlock_t;//这是一个结构体!
//我们可以任务这个结构体里面有两把锁!
//rdlock和wrlock
==读者优先和写者优先就是一种同步策略!==
//设置优先级的函数
int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref);
/*
pref 共有 3 种选择
PTHREAD_RWLOCK_PREFER_READER_NP (默认设置) 读者优先,可能会导致写者饥饿情况
PTHREAD_RWLOCK_PREFER_WRITER_NP 写者优先,目前有 BUG,导致表现行为和
PTHREAD_RWLOCK_PREFER_READER_NP 一致
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 写者优先,但写者不能递归加锁
*/