天天看點

寫者讀者問題(C#實作)

問題描述

有讀者和寫者兩組并發程序,共享一個檔案,當兩個或以上的讀程序同時通路共享資料時不會産生副作用,但若某個寫程序和其他程序(讀程序或寫程序)同時通路共享資料時則可能導緻資料不一緻的錯誤。是以要求:

①允許多個讀者可以同時對檔案執行讀操作;

②隻允許一個寫者往檔案中寫資訊;

③任一寫者在完成寫操作之前不允許其他讀者或寫者工作;

④寫者執行寫操作前,應讓已有的讀者和寫者全部退出。

讀者優先算法

在此算法中,讀程序是優先的,簡單來講,當存在讀者程序時,寫者操作将被延遲,并且隻要有一個讀者程序活躍,随後而來的讀者程序都将被允許通路檔案。這樣的方式下,會導緻寫者程序可能長時間等待,且存在寫者程序“餓死”的情況。

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();
            }
        }
    }
}

           

繼續閱讀