编写器/阅读器 锁

只允许一个线程对资源进行写操作,允许多个线程对资源进行读操作。一个线程进行写操作的时候,其他写线程及读线程阻塞

一个线程进行读操作时,其他写操作阻塞,读操作正常执行。
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadMonitorTest
{
    class Program
    {
        static Random rng = new Random();
        static byte[] buffer = new byte[100];
        static Thread writer;
        static ReaderWriterLock rwlock = new ReaderWriterLock();

        static void Main(string[] args)
        {

            // 初始化缓冲区
            for (int i = 0; i < 100; i++)
                buffer[i] = (byte)(i + 1);
            // 开始一个编写器线程
            writer = new Thread(new ThreadStart(WriterFunc));
            writer.Start();
            // 开始10 个阅读器线程
            Thread[] readers = new Thread[10];
            for (int i = 0; i < 10; i++)
            {
                readers[i] = new Thread(new ThreadStart(ReaderFunc));
                readers[i].Name = (i + 1).ToString();
                readers[i].Start();

            }
        }

        static void ReaderFunc()
        {
            // 循环直到编写器线程终止
            for (int i = 0; writer.IsAlive; i++)
            {
                int sum = 0;

                // 计算缓冲区中数值的和
                rwlock.AcquireReaderLock(Timeout.Infinite);
                try
                {
                    for (int k = 0; k < 100; k++)
                        sum += buffer[k];
                }
                finally
                {
                    rwlock.ReleaseReaderLock();
                }


                // 如果和不正确,报告错误
                if (sum != 5050)
                {
                    string message = String.Format("Thread {0} " +
                    "reports a corrupted read on iteration {1}",
                    Thread.CurrentThread.Name, i + 1);
                    Console.WriteLine(message);
                    writer.Abort();
                    return;
                }
            }
        }
        static void WriterFunc()
        {
            DateTime start = DateTime.Now;

            // 最多循环10 秒
            while ((DateTime.Now - start).Seconds < 10)
            {
                int j = rng.Next(0, 100);
                int k = rng.Next(0, 100);

                rwlock.AcquireWriterLock(Timeout.Infinite);
                try
                {
                    Swap(ref buffer[j], ref buffer[k]);
                }
                finally
                {
                    rwlock.ReleaseWriterLock();
                }
            }
        }
        static void Swap(ref byte a, ref byte b)
        {
            byte tmp = a;
            a = b;
            b = tmp;
        }
    }
}  

 

 
若需要嵌套使用读写锁,需将读写锁互相转换
 
                    //TODO: 向锁保护的资源读取

                    LockCookie cookie = rwlock.UpgradeToWriterLock(Timeout.Infinite);
                    try
                    {
                        //TODO:向锁保护的资源写入
                    }
                    finally
                    {
                        rwlock.DowngradeFromWriterLock(ref cookie);
                    }  

 

 
 
posted @ 2019-04-30 17:08  NCat  阅读(89)  评论(0)    收藏  举报