再上一篇中,介绍了生产者消费者模型[https://blog.csdn.net/Misszhoudandan/article/details/80715426]
今天介绍读者写者模型(读多写少的场景)
场景描述:
- 写者负责再资源池中写
- 读者负责从资源池中读数据
- 同一时间内不允许多个写者进行写,但允许多个读者进行读
- 当写者和读者都准备占用资源池时,写者优先占用资源池(此问题描述的时写者优先级高的场景)
建立模型
- 一个交易场所(资源池),此处用一个变量供读者和写者进行读写
- 两种角色,一组读者线程和一组写者线程
- 三种关系:
.读者和写者之间为互斥关系,写者优先级高
.读者和读者之间为共享关系(没有互斥关系)
.写者和写者之间为互斥关系
代码实现
这里采用POXI线程库中的读写锁来实现
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
//读者写者模型(读的频率高,写的频率低)
//读者和读者之间关系为 共享
//写者和写者之间关系为 互斥
//读者和写者之间关系为 同步互斥关系
//读写锁
//读者加读锁(读者之间共享)
//写者加写锁(写者之间互斥)
//写者优先获取锁(写者优先级高)
pthread_rwlock_t rw_lock;//定义一个读写锁
//*******实现一个交易场所********************
int count;
//***********实现三种关系**********************
//实现写着
void * Write(void * arg)
{
(void)arg;
while(1)
{
usleep(1000);
pthread_rwlock_wrlock(&rw_lock);//在写之前加写锁
printf("写入:%d\n",++count);
pthread_rwlock_unlock(&rw_lock);//写之后释放锁
usleep(7658);
}
return NULL;
}
//实现读者
void * Read(void * arg)
{
(void)arg;
while(1)
{
pthread_rwlock_rdlock(&rw_lock);//在读之前加读锁
printf("读出:%d\n",count);
pthread_rwlock_unlock(&rw_lock);//读之后释放锁
usleep(500);
}
return NULL;
}
//******************两种角色*******************
void test()
{
const int N=8;
pthread_t thread[N];
int i=0;
pthread_rwlock_init(&rw_lock,NULL);//对读写锁进行初始化
//创建写者线程
for(i=0;i<N/2;i++)
{
pthread_create(&thread[i],NULL,Write,NULL);
}
//创建读者线程
for(i=0;i<N-N/2;i++)
{
pthread_create(&thread[i],NULL,Read,NULL);
}
//等待线程结束
for(i=0;i<N;i++)
{
pthread_join(thread[i],NULL);
}
pthread_rwlock_destroy(&rw_lock);//销毁读写锁
}
int main()
{
test();
return 0;
}
结果展示:
我们看到写者之间是互斥的(每次写入的值都不同)
读者之间是共享的(可以读出相同的值)