目录
目录
1,场景
2,接口
3,场景模拟
1,场景
有一种场景,读者多,写者少,绝大多数的情况下我们都是在进行读取而不修改,只有少数的情况下我们才会修改。
场景一:比如学校在官网上面发布了一个优秀学生名单,现在公示一个礼拜,我们发现这一个礼拜查看的人非常多,但是修改的人几乎没有,只有学生对名单不满,举报啥的,学院核实才会进行修改。这样的场景如果我们每一次访问那个公共的资源学生名单,我们进行加锁保护,我们使用互斥锁当然是可以的,但是这样会不会代价太大了啊,因为大部分都是读啊,对于读来说,我们是希望他是并行的啊,对于写我们才希望是串行的。
当前状态 | 读锁加锁 | 写锁加锁 |
无锁 | 可以 | 可以 |
读锁 | 可以 | 阻塞 |
写锁 | 阻塞 | 阻塞 |
由这个标可以看出读者的访问时并行的,写者的修改时串行的,并且在写者准备写的时候要包装没有读者在读,这样才一抢到锁区写,并且在写的时候所有的读者都是阻塞的,
一些处理机制:读者优先,写者优先,等需要程序员自己去控制代码来实现。
2,接口
这里的接口和前面的用法都是一样的,这就是pthread感觉写的非常nice,用起来非常的简单,直接类比者用就完事来。
1,初始化
和之前一样,先定义一把锁,pthread_rwlock_t;
之后的传参和前面互斥锁一样的,没啥变化。
2,销毁
把需要销毁的锁地址传过去就好了。
3,加锁
加读锁
加写错
4,解锁
俩种加锁用同一种解锁
3,场景模拟
模拟一个买票的场景,我们假设一大波人只是查看剩余的票数,而只有较少的一部分人时正真买票的。我们可以搞一个读写多控制。
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
using namespace std;
volatile int tick =5;
// 测试读写锁。
pthread_rwlock_t rwlock;
void *reader(void *args)
{
char *str = (char *)args;
while (true)
{
pthread_rwlock_rdlock(&rwlock);
cout << "我是读者: " << str << " 剩余票数->:" << tick << endl;
pthread_rwlock_unlock(&rwlock);
usleep(100000);
//sleep(1);
}
}
void *writer(void *args)
{
char *str = (char *)args;
while (true)
{
pthread_rwlock_wrlock(&rwlock);
if (tick < 0)
{
cout << "没有票了。我是" << str << "退出抢票" << endl;
}
else
{
tick--;
cout << "我是写者 " << str << "抢到票号:->" << tick << endl;
}
pthread_rwlock_unlock(&rwlock);
// usleep(1000);
sleep(3);
}
}
int main()
{
pthread_rwlock_init(&rwlock, nullptr);
pthread_t read1;
pthread_t read2;
pthread_t read3;
pthread_t read4;
pthread_t read5;
pthread_t write1;
pthread_t write2;
pthread_create(&read1,nullptr,reader,(void*)"read1");
pthread_create(&read2,nullptr,reader,(void*)"read2");
pthread_create(&read3,nullptr,reader,(void*)"read3");
pthread_create(&read4,nullptr,reader,(void*)"read4");
pthread_create(&read5,nullptr,reader,(void*)"read5");
pthread_create(&read1,nullptr,writer,(void*)"writer1");
pthread_create(&read2,nullptr,writer,(void*)"writer2");
while(true)
{
sleep(1);
}
pthread_rwlock_destroy(&rwlock);
return 0;
}
视频效果
读写锁测试
我们发现读的话值并行的,而写的话是串行的,但这这个效果一点呢都不明显。
我们把读锁时间调整为1妙,写锁调整为10妙,都可以看到读是并行的。