29.4.1 Event构造
class Program { static void Main() { int x = 0; const int iterations = 10000000; Stopwatch sw = Stopwatch.StartNew(); // 1 for (int i = 0; i < iterations; i++) { x++; } Console.WriteLine("incrementing x:{0:N0}", sw.ElapsedMilliseconds); // 2 sw.Restart(); for (int i = 0; i < iterations; i++) { M(); x++; M(); } Console.WriteLine("incrementing in M x:{0:N0}", sw.ElapsedMilliseconds); // 3 SpinLock s1 = new SpinLock(); sw.Restart(); for (int i = 0; i < iterations; i++) { bool taken = false; s1.Enter(ref taken); x++; s1.Exit(); } Console.WriteLine("incrementing in SpinLock x:{0:N0}", sw.ElapsedMilliseconds); // 4 using (SimpleWaitLock sw1 = new SimpleWaitLock()) { sw.Restart(); for (int i = 0; i < iterations; i++) { sw1.Enter(); x++; sw1.Leave(); } Console.WriteLine("incrementing x in SimpleWaitLock:{0:N0}", sw.ElapsedMilliseconds); } //incrementing x:44 //incrementing in M x:174 //incrementing in SpinLock x:3,186 //incrementing x in SimpleWaitLock: 33,481 Console.ReadKey(); //bool createdNew; //此代码 仅供看 //using (new Semaphore(0, 1, "SomeUniqueStringIdentifyingMyApp", out createdNew)) //{ //} } [MethodImpl(MethodImplOptions.NoInlining)] private static void M() { } } internal sealed class SimpleWaitLock : IDisposable { private readonly AutoResetEvent m_available; public SimpleWaitLock() { m_available = new AutoResetEvent(true); //最开始可自由使用 } public void Enter() { //在内核中阻塞,直到资源可用 m_available.WaitOne(); } public void Leave() { //让另一个线程访问资源 m_available.Set(); } public void Dispose() { m_available.Dispose(); } }
29.4.3 Mutex构造
/// <summary> /// 递归式AutoResetEvent优化版本 /// </summary> internal sealed class RecursiveAutoResetEvent : IDisposable { private AutoResetEvent _lock = new AutoResetEvent(true); private int _owningThreadId = 0; private int _recursionCount = 0; public void Enter() { int currentThreadId = Thread.CurrentThread.ManagedThreadId; //如果调用线程拥有锁,就递增递归计数 if (_owningThreadId == currentThreadId) { _recursionCount++; return; } //调用线程不拥有锁,等待它 _lock.WaitOne(); //调用的线程拥有了锁,初始化拥有锁的线程的ID和递归计数 _owningThreadId = currentThreadId; _recursionCount = 1; } public void Leave() { //如果调线程不拥有锁,就出错了 if (_owningThreadId != Thread.CurrentThread.ManagedThreadId) throw new InvalidOperationException("调线程不拥有锁"); //从递归数减1 if (--_recursionCount==0) { //如果递归计数 为0,表明没有线程拥有锁 _owningThreadId = 0; _lock.Set(); //唤醒一个正在等待的线程(如果有的话) } } public void Dispose() { _lock.Dispose(); } } /// <summary> /// Mutex互斥锁 /// </summary> internal sealed class SomeClass : IDisposable { private readonly Mutex _lock = new Mutex(); public void Method1() { _lock.WaitOne(); //随便做什么事情 Method2(); //Method2递归获取锁 _lock.ReleaseMutex(); } public void Method2() { _lock.WaitOne(); //随便做什么事情 _lock.ReleaseMutex(); } public void Dispose() { _lock.Dispose(); } }