Linux多线程(读者写者问题与自旋锁)

一、读者写者模型

读者写者模型类似于生产者消费者模型。同样符合321原则,即三种关系,两个角色,一个交易场所。

1.适用场景

1.对数据大部分是进行读取,少量的操作是写入。
2.判断一句是进行数据读取,而不像生产者消费者模型那样将数据取走。

2.321原则

读者与读者:没有关系。
写者与写者:互斥关系。
读者与写者:互斥关系。
交易场所可以是一段缓冲区,可以是自己申请的,也可以是STL容器。

3.与生产者消费者模型的区别

根本区别在于,读者不会取走资源,而消费者会取走资源。

4.读写锁

在这里插入图片描述
这两个函数分别为创建和销毁读写锁的函数。
在这里插入图片描述
以读者身份加锁。
在这里插入图片描述
以写的身份加锁。

5.伪代码理解

(1)pthread_rwlock_wrlock()

mtx1.lock();
while(readers>0)
{
	wait();
}
//进入临界区
mtx1.unlock();

(2)pthread_rwlock_rdlock()

mtx1.lock();
readers++;
mtx1.unlock();
//进入临界区
mtx1.lock();
readers--;
mtx1.unlock();

其中readers表示的是临界资源。

6.优先级

读者优先:读者和写者同时到来的时候,读者先进入访问。
写者优先:读者和写者同时到来的时候,比当前写者晚来的所有读者,都不要进入临界区访问了,临界区没有读者的时候让写者写入。

由于读者多写者少,因此是存在饥饿问题的。

二、自旋锁VS挂起等待特性的锁

目前我们学习的都是挂起等待特性的锁。
下面举一个多线程的例子引出自旋锁。
在这里插入图片描述
假设有多个线程访问临界资源,因此需要对临界资源加锁处理,当访问临界资源时间比较长的时候,需要加挂起等待锁,即没有抢到锁的线程挂起等待。
当访问临界资源时间比较短的时候,此时没有抢到锁的线程可以不挂起等待,而是不断通过循环检测锁的状态,一旦释放就立刻去竞争。这种情况我们加的锁的类型称为自旋锁。
注意,判断访问临界资源时间长短是由程序员判断的,因此锁的选择也是程序员选择的。
以下为自旋锁的两个函数:
在这里插入图片描述
在这里插入图片描述

posted @ 2022-09-24 20:28  卖寂寞的小男孩  阅读(88)  评论(0)    收藏  举报