29.4 内核模式构造
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(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了