🤔水文🤢
读者写者模型
- 对数据,大部分的操作是读取,少量的操作是写入
- 判断依据就是进行数据读取(消费的一段),是否会将数据取走,如果不去走就可以考虑读者写者模型
出黑板报,一个人在写,多个人在读
写者和写者:竞争互斥关系
读者和写者:互斥关系(要保证写完我才能来读,避免没有写完读的数据不准确,我在看的时候,你擦了不可以),
同步关系(我们写完了就可以让读者来读,读完了让写者来写)
读者和读者之间:没有关系
生产消费vs读者写者
根本原因:读者不会取走资源,而消费者会拿走数据
使用代码完成读者写者模型:使用锁来维护上面三种关系,又线程承担
321原则
3:三种关系
读者和读者
读者和写着
写者和写者
2:两种角色
读者和写者
3:一个交易场所
提供一段缓冲区(我们自己申请的,还是stl)
示例
- 新闻发布(我们写的博客,也适合)
接口
pthread_rwlock_t rwlock //数据类型
pthread_rwlock_init(pthread_rwlock_t*rwlock,pthread_rwlock_t* attr); //初始化
pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) //以读者的身份加锁
pthread_rwlock_tryrdlock(pthread_rwlock_t * rwlock)
//以写者方式加锁
pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
//释放都是一样的
pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
如何理解伪代码
写者 int readers=0
mtx1.lock()//写者先加锁
while(readers>0)//读者大于0
{
//
wait(mtx1,)//等待
}
写者
//读者和写者竞争一把锁,进来发现为0,就解锁
mtx1.unlock()
//待补充
进入临界区
读者
mtx1.lock()
readers++;
mtx1.unlock()
mtx1.lock()
readers--;
mtx1.unlock()
优先级:
读者优先:让我们的读者和写者同时到来的时候,让读者先进入访问,
写者优先:当读者和写者同时到来的时候,比当前写者晚来的所有的读者都不要进入临界区访问了,等临界区中没有读者的时候,让写先写入,
但是这样,(读者多,写者少),所以会出现写饥饿问题(中性词),当我们的数据都被读完之后再给修改,
自旋锁
挂起等待特性的锁vs自旋锁
挂起等待的锁:
挂起等待:就是时间等待的久
自旋:就是等待的时间不多,就一会一会就询问情况
多个线程访问一个临界资源
一开始就是加锁,后面解锁
线程访问临界资源,花费的时长问题??
- 如果访问花费的时间很长,就适合挂起等待锁
- 如果花费的时间很短,那么就适合自旋锁
线程如何得知,自己会再临界资源里面待多长时间呢?
线程不知道!程序员知道!
等待的时间短,就使用这个自旋锁
pthread_spin_t 和其他锁都一样,