問題描述
有讀者和寫者兩組并發程序,共享一個檔案,當兩個或以上的讀程序同時通路共享資料時不會産生副作用,但若某個寫程序和其他程序(讀程序或寫程序)同時通路共享資料時則可能導緻資料不一緻的錯誤。是以要求:
①允許多個讀者可以同時對檔案執行讀操作;
②隻允許一個寫者往檔案中寫資訊;
③任一寫者在完成寫操作之前不允許其他讀者或寫者工作;
④寫者執行寫操作前,應讓已有的讀者和寫者全部退出。
讀者優先算法
在此算法中,讀程序是優先的,簡單來講,當存在讀者程序時,寫者操作将被延遲,并且隻要有一個讀者程序活躍,随後而來的讀者程序都将被允許通路檔案。這樣的方式下,會導緻寫者程序可能長時間等待,且存在寫者程序“餓死”的情況。
using System;
using System.Threading;
/*讀者優先*/
namespace ConsoleApp1
{
class Program
{
private static Semaphore RWMutex; // 讀寫互斥信号量
private static Semaphore CountMutex; //讀者計數互斥信号量
private static int Rcount = 0; // 正在進行讀操作的讀者數目
static void Main(string[] args)
{
RWMutex = new Semaphore(1, 1);
CountMutex = new Semaphore(1, 1);
Thread Writer = new Thread(writer);
Thread Reader0 = new Thread(reader);
Thread Reader1 = new Thread(reader);
Thread Reader2 = new Thread(reader);
Writer.Start();
Reader0.Start();
Reader1.Start();
Reader2.Start();
}
//寫者程序
protected static void writer()
{
while (true)
{
RWMutex.WaitOne(); // 判斷是否可以寫
Console.WriteLine("write");
Thread.Sleep(1000);
RWMutex.Release(); // 寫完成,釋放資源
}
}
//讀者程序
protected static void reader()
{
while (true)
{
CountMutex.WaitOne(); // 互斥通路count變量
Rcount++;
if (Rcount == 1) // 第一個讀程序占用寫程序的資源
{
RWMutex.WaitOne();
}
CountMutex.Release();
Console.WriteLine("read-" + Rcount);
Thread.Sleep(1000);
CountMutex.WaitOne();
Rcount--;
if (Rcount == 0) // 最後一個讀程序釋放寫程序的資源
{
RWMutex.Release();
}
CountMutex.Release();
}
}
}
}
寫者優先算法
如果希望寫程序優先,即當有讀程序正在讀共享檔案時,有寫程序請求通路,這時應禁止後續讀程序的請求,等待到已在共享檔案的讀程序執行完畢則立即讓寫程序執行,隻有在無寫程序執行的情況下才允許讀程序再次運作。
using System;
using System.Threading;
//寫者優先
namespace ConsoleApp1
{
class Class1
{
private static Semaphore RCMutex, WCMutex; // 讀者、寫者計數互斥
private static Semaphore rsem, wsem; // 讀寫互斥
private static int Rcount = 0, Wcount = 0; // 讀者、寫者計數
static void Main(string[] args)
{
RCMutex = new Semaphore(1, 1);
WCMutex = new Semaphore(1, 1);
rsem = new Semaphore(1, 1);
wsem = new Semaphore(1, 1);
Thread Writer = new Thread(writer);
Thread Reader = new Thread(reader);
Reader.Start();
Writer.Start();
}
//writer
protected static void writer()
{
while (true)
{
WCMutex.WaitOne();
Wcount++;
if (Wcount == 1)
{
rsem.WaitOne();
}
Thread.Sleep(1000);
WCMutex.Release();
wsem.WaitOne();
Console.WriteLine("write-" + Wcount);
wsem.Release();
WCMutex.WaitOne();
Wcount--;
if (Wcount == 0)
{
rsem.Release();
}
WCMutex.Release();
}
}
//reader
protected static void reader()
{
while (true)
{
rsem.WaitOne();
RCMutex.WaitOne();
Rcount++;
if (Rcount == 1)
{
wsem.WaitOne();
}
Thread.Sleep(1000);
RCMutex.Release();
rsem.Release();
Console.WriteLine("read-" + Rcount);
RCMutex.WaitOne();
Rcount--;
if (Rcount == 0)
{
wsem.Release();
}
RCMutex.Release();
}
}
}
}
公平競争算法
using System;
using System.Threading;
namespace ConsoleApp1
{
class Class2
{
//
private static Semaphore RCMutex, WCMutex, RMutex, WMutex;
private static int Rcount = 0;
static void Main(string[] args)
{
RCMutex = new Semaphore(1, 1);
WCMutex = new Semaphore(1, 1);
RMutex = new Semaphore(1, 1);
WMutex = new Semaphore(1, 1);
Thread Writer0 = new Thread(writer);
Thread Reader0 = new Thread(reader);
Reader0.Start();
Writer0.Start();
}
public static void reader()
{
while (true)
{
Console.WriteLine("reader waiting");
RMutex.WaitOne();
RCMutex.WaitOne();
Rcount++;
if (Rcount == 1)
{
WMutex.WaitOne();
}
RCMutex.Release();
Console.WriteLine("read-" + Rcount);
Thread.Sleep(1000);
RCMutex.WaitOne();
Rcount--;
if (Rcount == 0)
{
WMutex.Release();
}
RCMutex.Release();
RMutex.Release();
}
}
public static void writer()
{
while(true)
{
Console.WriteLine("Writer waiting");
RMutex.WaitOne();
WMutex.WaitOne();
Console.WriteLine("write");
Thread.Sleep(1000);
WMutex.Release();
RMutex.Release();
}
}
}
}