写者读者问题(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();
            }
        }
    }
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值