C#模拟读者写者问题

原本是操作系统的一个上机作业,上课没注意听所以一直都不知道,明天都要交了只好用C#简单写了个,好在.NET强大的FCL提供了读者写者锁类,因此实现起来方便许多,读者写者锁在读者数目多于写者时会显示出比监视器(类似于操作系统中讲到的管程)更好的性能。具体的说,每个读者线程在访问临界资源的时候申请读者锁,访问结束后释放锁,同样,写者线程在访问资源时申请写者锁,访问结束释放锁。如果锁被一个写者线程而不是读者线程所拥有的话,AcquireReaderLock会被阻塞,锁被任何一个线程拥有,AcquireWriterLock都会被阻塞。这样也就实现了多个线程可并发读取临界资源但任意时刻只能有一个线程执行写操作,并且如果有线程在读,写线程将无法进入。按照上述,便基本解决了读者-写者问题,但是很明显这种解决方案是读线程优先的。

以下是具体的代码实现,模拟两个写者和四个读者,有不妥的地方希望及时指正哈

 

using  System;
using  System.Threading;

namespace  Reader_Writer
{
    
class  Reader_Writer
    {
        
static  Random rnd  =   new  Random( unchecked (( int )DateTime.Now.Ticks));
        
// 缓冲区模拟有100页的书
         static   byte []  buffer  =   new   byte [ 100 ];
        
static  ReaderWriterLock rwlock  =   new  ReaderWriterLock();
        
static  Thread[] writers  =   new  Thread[ 2 ];
        
static  Thread[] readers  =   new  Thread[ 4 ];

        
static   void  Main( string [] args)
        {
            
string [] writerNames  =  { " W1 " " W2 " };
            
string [] readerNames  =  { " R1 " " R2 " " R3 " " R4 " };
            
// 初始化书本内容
             for  ( int  i = 0 ; i < 100 ; i ++ )
            {
                buffer[i] 
=  ( byte )(i + 1 );
            }
            
// 初始化2个写者线程
             for  ( int  i = 0 ; i < 2 ; i ++ )
            {
                writers[i] 
=   new  Thread( new  ThreadStart(WriteMethod));
                writers[i].Name 
=  writerNames[i];
            }
            
// 初始化4个读者线程
             for  ( int  i = 0 ; i < 4 ; i ++ )
            {
                readers[i] 
=   new  Thread( new  ThreadStart(ReadMethod));
                readers[i].Name 
=  readerNames[i];
            }

            
// 指定线程开始执行的顺序,可调整
            readers[ 0 ].Start();
            writers[
0 ].Start();
            readers[
1 ].Start();
            writers[
1 ].Start();
            readers[
2 ].Start();
            readers[
3 ].Start();
        }

        
static   void  ReadMethod()
        {
            
// 申请读者锁,在此期间允许其他读者但阻止任何写者
            rwlock.AcquireReaderLock(Timeout.Infinite);
            
try
            {
                
int  page  =  rnd.Next( 1 101 );
                Console.WriteLine(
" 读者线程 {0} 正在读第 {1} 页... " , Thread.CurrentThread.Name, page);
                
// 模拟读过程
                Thread.Sleep(rnd.Next( 3000 6000 ));
                Console.WriteLine(
" 读者线程 {0} 完成读操作. " , Thread.CurrentThread.Name);
            }
            
catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
finally
            {
                
// 释放读者锁
                rwlock.ReleaseReaderLock();
            }
        }

        
static   void  WriteMethod()
        {
            
// 申请写者锁,在此期间阻止任何读者和写者
            rwlock.AcquireWriterLock(Timeout.Infinite);
            
try
            {
                Console.WriteLine(
" 写者线程 {0} 开始工作... " , Thread.CurrentThread.Name);
                
int  page  =  rnd.Next( 1 101 );
                Console.WriteLine(
" 写者线程 {0} 正在改写第 {1} 页的内容 " , Thread.CurrentThread.Name, page);
                Thread.Sleep(rnd.Next(
3000 6000 ));
                Console.WriteLine("写者线程 {0} 完成工作... ", Thread.CurrentThread.Name);
            }
            
catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
finally
            {
                
// 释放写者锁
                rwlock.ReleaseWriterLock();
            }
        }
    }
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值