算法设计原理:
(a)为了实现读者和写者的进程互斥设置了两个互斥信号量rmutex、wmutex,再设置两个整型变量Rcount,Wcount,分别记录正在占用临界资源变量的读者和写者数量,同时又设置互斥信号量RCMutex和WCMutex,实现对于Rcount和Wcount操作的阻塞。
(b)规则:读者之间不互斥,只要有一个读者在读,那么写者就不能进去写,反之,只要有一个写者在写,那么读者就不能进去读。因此,仅当Rcount或者Wcount=1时,表示进程就会执行wait(wmutex)或者wait(rmutex)的操作,以阻塞其他人的活动。
(c)三种情况:读者优先:在写者的行动函数前面加一句wmutex.WaitOne();表示如果要执行写者操作就必须先等待读者将这个变量释放,而只要还有一个读者,这个临界变量就会被阻塞,这就实现了只要有读者在看书,写者就不能提出申请的作用。
写者优先:在相应的Reader函数的第一行加一句 rmutex.WaitOne();而Writer里面的内容表示一旦有写者提出申请就会自动将这个临界变量阻塞。这样就实现了阻塞后面的reader继续提出申请的目的。
公平竞争:Reader和Writer互不阻塞,先到先申请。
伪代码:
semphore rmutex=1,wmutex=1;
int Rcount=0;
void reader(){
do{
wait(rmutex);
if(Rcount0)wait(wmutex);
Rcount++;
signal(rmutex);
…
reading
…
wait(rmutex);
Rcount–;
if(Rcount0)signal(wmutex);
signal(rmutex);
}while(TRUE);
}
void Writer(){
do{
wait(wmutex);
writing
signal(wmutex);
}while(TRUE);
}
void main(){
cobegin
Reader();Writer();
coend
}
完整代码(C#):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace WR
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private static bool StopFlag = false;
private void button1_Click_1(object sender, EventArgs e)
{
StopFlag = false;
Writer1.Text = "";
Reader1.Text = "";
Buffer.Text = "";
Startprogram();
}
private void button2_Click_1(object sender, EventArgs e)
{
StopFlag = true;
}
private static Semaphore RCMutex= new Semaphore(1, 1); // 读者计数互斥
private static Semaphore WCMutex = new Semaphore(1, 1);// 写者计数互斥
private static Semaphore rmutex = new Semaphore(1, 1); // 读者互斥
private static Semaphore wmutex = new Semaphore(1, 1); // 写者互斥
private static int Rcount = 0, Wcount = 0; // 读者、写者计数
private static int Rid = 0, Wid = 0;//读者、写者的