抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > 读者写者问题(读者优先)

读者写者问题(读者优先)

时间:2022-01-30 19:22:26

相关推荐

一、读者写者问题定义

存在一个多个进程共享的数据区,该数据区可以是一个文件或一块内存空间,甚至可以是一组寄存器:有些进程(reader)只读取这个数据区中的数据,有些进程(writer)只往数据区中写数据。

此外,还必须满足以下条件

1、任意数量的读进程可同时读这个文件。

2、一次只能有一个写进程可以写文件。

3、若存在一个写进程正在写文件,则禁止任何读进程读文件。

4、若存在读进程正在读文件,则任何写进程需等待,直至当前的读进程全部执行读操作完毕!

也就是说,读进程不需要排斥其他读进程,而写进程需要排斥其他所有进程。

二、读者优先(C++代码)

#include <iostream>#include <pthread.h>#include <semaphore.h>#include <unistd.h>//sleep函数using namespace std;//信号量的数据类型为结构sem_t,它本质上是一个长整型的数sem_t RW, Mutex;//信号量 int readCounts = 0;typedef struct DATA{int id;int set_upTime;//启动时间 int exeTime;//执行时间 }data;/* 测试例子 1 R 2 62 W 3 53 R 6 34 R 4 65 W 3 6*/ //读者void* Reader(void* tem) {int id = ((data*)tem)->id;int set_upTime = ((struct DATA*)tem)->set_upTime;int exeTime = ((data*)tem)->exeTime;sleep(set_upTime);printf("线程 %d: 等待“读”\n", id);//用于确保readCounts被正确更新 sem_wait(&Mutex);//P//用来阻塞当前线程直到信号量mutex的值大于0, //解除阻塞后将mutex的值减一,表明公共资源经使用后减少。 readCounts++;if(readCounts == 1)sem_wait(&RW);//等待读写权,且有优先使用权(较于写者)情况是当队列中有读者写者//且读者排在写者前面,那么后来的读者可以排在最后一个等待读的后面/第一个等待写的前面 sem_post(&Mutex);//V printf("线程 %d: 开始“读”\n", id);sleep(exeTime);printf("线程 %d:“读”结束\n", id);sem_wait(&Mutex);readCounts--;if(readCounts == 0)sem_post(&RW);//解锁 sem_post(&Mutex);pthread_exit(0);}//写者void* writer(void* tem) {int id = ((data*)tem)->id;int exeTime = ((DATA*)tem)->exeTime;int set_upTime = ((struct DATA*)tem)->set_upTime;sleep(set_upTime);printf("线程 %d: 等待“写”\n", id);sem_wait(&RW);//P 等待读写权 printf("线程 %d: 开始“写”\n", id);sleep(exeTime);printf("线程 %d:“写”结束\n", id);sem_post(&RW);//释放读写权 pthread_exit(0);}int main() {int id = 0;pthread_t tid; //用于声明线程IDpthread_attr_t attr; //线程 属性 //pthread_attr_init(&attr);//初始化一个线程对象 sem_init(&Mutex, 0, 1);//用来初始化一个信号量//第一个参数: 信号量名//第二个参数: 表示允许几个进程共享该信号量,0表示用于进程内的多线程共享//第三个参数: 表示可用的资源的数目sem_init(&RW, 0, 1);cout<<"请依次输入以下四项信息"<<endl;cout<<"线程ID"<<" | "<<"身份"<<" | "<<"启动时间"<<" | "<<"执行时间"<<endl<<endl; while(scanf("%d", &id) != EOF) {char role;//读者"R" or 写者"W" int set_upTime;//启动时间int exeTime; //运行时间scanf("%c%d%d", &role, &set_upTime, &exeTime);//data* d = ( data*)malloc(sizeof( data));data* d = new DATA;//本句和上一句效果是一样的d->id = id;d->set_upTime = set_upTime;d->exeTime = exeTime;if(role == 'R'||role == 'r') {printf("创建线程 %d: 读者\n\n", id);//Reader Create the %d threadpthread_create(&tid, &attr, Reader, d);//创建线程 //第一个参数为指向线程 标识符的 指针//第二个参数用来设置线程属性//第三个参数是线程运行函数的起始地址//最后一个参数是运行函数的参数}else if(role == 'W'||role == 'w') {printf("创建线程 %d: 写者\n\n", id);//Writerpthread_create(&tid, &attr, writer, d);}//cout<<"Read/Write operations all execute over!"<<endl;}//信号量销毁sem_destroy(&Mutex);sem_destroy(&RW);return 0;}

三、代码说明

写进程比较简单,信号量RW用于实施互斥,只要一个写进程正在访问共享数据区时。其他写进程和读进程都不能访问它。

读进程也使用RW实施互斥,但为了允许多个读进程在没有读进程正在读时,第一个试图读的读进程需要在RW上等待。当至少已有一个读进程正在读时,随后的读进程无须等待,可以直接进入,全局变量readCounts用于记录读进程的数量,信号量Mutex用于确保readCounts被正确地更新。

此内容为操作系统书中知识,比较简单、易实现,适于学习、理解信号量原理。

转载需说明!

如果觉得《读者写者问题(读者优先)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。