编写器/阅读器 锁
只允许一个线程对资源进行写操作,允许多个线程对资源进行读操作。一个线程进行写操作的时候,其他写线程及读线程阻塞。
一个线程进行读操作时,其他写操作阻塞,读操作正常执行。
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); }
真正的大师永远怀着一颗学徒的心。

浙公网安备 33010602011771号