问题描述:
有读者和写者两个并发的进程,他们共享一个文件资源,当两个或者以上进程读取文件的时候不会产生副作用,但是如果写进程和其他的进程同时访问共享文件的时候就会产生错误。因此就有:读者可以同时读取文件;写者只能和其他进程互斥写入文件。
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct semaphore {
int mutex;//用于保护更新count变量时互斥,其值为1时表示可以修改
int rw; //用于保证读者和写者互斥访问共享文件,其值为1是表示可以使用共享文件
int w; //用于实现“写进程优先”,其值为0时表示有写进程在使用共享文件
int count;//用于记录当前的读者数量
}*semaphoreptr;
int file;//模拟共享文件
class Progress {
public:
int sign;
Progress():sign(0){}
~Progress(){}
virtual void wait(semaphoreptr s) = 0;
virtual void signal(semaphoreptr s) = 0;
};
class Writer :public Progress {
public:
void wait(semaphoreptr s);
void signal(semaphoreptr s);
};
//写者申请使用共享文件
void Writer::wait(semaphoreptr s) {
if (s->rw == 1 && s->w == 1) {
//表示可以进行写操作,关闭共享文件使用权限
s->rw = 0;
s->w = 0;
sign = 1;//表示可以进行写入操作
}
else {
//不能进行写操作
cout << "有进程占用共享文件,不能进行写操作..." << endl;
}
}
void Writer::signal(semaphoreptr s) {
if (this->sign == 1) {
//可以进行写入操作
file = 6;
cout << "写入操作完成..." << endl;
s->rw = 1;//释放共享文件
s->w = 1;//恢复对共享文件的访问
this->sign = 0;
}
else {
cout << "有进程占用共享文件,不能进行写入操作..." << endl;
}
}
class Reader :public Progress {
public:
void wait(semaphoreptr s);
void signal(semaphoreptr s);
};
void Reader::wait(semaphoreptr s) {
if (s->w == 1) {
//表示没有写进程访问共享文件
if (s->mutex == 1) {
//表示可以访问count变量
s->rw = 0;//阻止写进程访问
//s->w = 0;
s->count++;//正在读取共享文件的进程数
this->sign = 1;//表示已经成功申请了共享文件访问权
}
else {
cout << "有其他进程在申请修改访问进程数量,修改不成功..." << endl;
return;
}
}
else {
cout << "有写进程正在访问共享文件,不能进行读操作..." << endl;
return;
}
}
void Reader::signal(semaphoreptr s) {
if (this->sign == 1) {
//表示可以进行读操作
cout << "文件的内容是" << file << "读取成功..." << endl;
//释放使用权限
s->w = 1;
this->sign = 0;
}
else {
cout << "该进程没有申请到使用权,无法进行读操作..." << endl;
return;
}
if (s->mutex == 1) {
s->count--;
if (s->count == 0)
s->rw = 1;//如果是最后一个访问的进程,则允许写进程写
}
else {
cout << "有其他进程正在申请修改访问进程数量,修改不成功..." << endl;
return;
}
}
int main()
{
semaphoreptr s = (semaphore *)malloc(sizeof(semaphore));
s->count = 0;
s->mutex = 1;
s->rw = 1;
s->w = 1;
Writer w1;
Reader r1, r2;
w1.wait(s);
w1.signal(s);
r1.wait(s);
r1.signal(s);
w1.wait(s);
r1.wait(s);
w1.signal(s);
r1.wait(s);
r2.wait(s);
r1.signal(s);
r2.signal(s);
return 0;
}
调试结果:
参考书籍:王道 《2018年操作系统考研复习指导》