前一节介绍完了生产者消费者模型,它是一种一方生产数据,另一方消费数据的模式,下面介绍另外一种不同于生产消费的模型。即读者写者模型。
两者相同:
和前面的模型相比,读写模型中写者与写者之间还是互斥关系,写者与读者之间还是互斥与同步关系。
两者差异:
和生产消费模型不同的一点是,当一个写者写入数据后,可以有多个读者进行读取数据,举个简单易懂的例子就是,老师布置的作业,你写完后,可以让你的其他舍友都抄,而不是只能某一个舍友抄后,而其他舍友就不能抄。
在前面的生产者消费者模型里,消费者和消费者之间是互斥的关系,而读写模型里,写者与写者之间是没有任何关系的。
相关函数:
读者锁
写者锁
解锁函数
下面是一个多读者多写者模型:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int global_num = 10;
void err_exit(const char *err_msg)
{
printf("error:%s\n",err_msg);
exit(1);
}
void *thread_read_lock(void *arg)
{
char *pthr_name = (char *)arg;
while(1)
{
//add readlock
pthread_rwlock_rdlock(&rwlock);
printf("pthread:%sEnter critical zone...,global_num = %d\n",pthr_name,global_num);
sleep(1);
printf("pthread:%sLeave critical zone...\n",pthr_name);
//del readlock
pthread_rwlock_unlock(&rwlock);
sleep(1);
}
return NULL;
}
void *thread_write_lock(void *arg)
{
char *pthr_name = (char *)arg;
while(1)
{
//add readlock
pthread_rwlock_wrlock(&rwlock);
global_num++;
printf("pthread:%sEnter critical zone...,global_num = %d\n",pthr_name,global_num);
sleep(1);
printf("pthread %sLeave critical zone...\n",pthr_name);
//del wlock
pthread_rwlock_unlock(&rwlock);
sleep(2);
}
return NULL;
}
int main()
{
pthread_t tid_read_1,tid_read_2,tid_write_1,tid_write_2;
if(pthread_create(&tid_read_1,NULL,thread_read_lock,"read_1") != 0)
err_exit("create tid_raed_1");
if(pthread_create(&tid_read_2,NULL,thread_read_lock,"read_2") != 0)
err_exit("create tid_raed_2");
if(pthread_create(&tid_write_1,NULL,thread_write_lock,"write_1") != 0)
err_exit("create tid_write_1");
if(pthread_create(&tid_write_2,NULL,thread_write_lock,"write_2") != 0)
err_exit("create tid_write_2");
if(pthread_join(tid_read_1,NULL) != 0)
err_exit("pthread_join()");
return 0;
}
从结果我们也可以很明显的看出,写者与写者之间的互斥关系,当一个写者在进行写操作时,其他的写者不能在进行写操作,而反观读者,几个读者可以同时访问临界区的资源,互相之间并没有什么特定的关系。
上面就是关于读者写者模型的一点简介,这个模型相对来说还是比较简单的,代码部分呢,也借用了一些网上毕竟经典且易于理解的部分。