Web常用工具 二维码美化 在线压缩 JavaScript AI工具汇总网站 ASP.NET控件源码查询 W3CHTML W3SCHOOL TypeScript 开源中国 51aspx github codeproject SQLBACKUP 几种排序算法比较 SQL中deny权限 MSDN下载 HttpWebRequest类 HTML5 stackoverflow ASP.NET 页生命周期概述 IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 [SQL Server]视图sys.sysprocesses brnshop学习 SQL视频 Fiddler帮助文档 Sprint.Net SQLServer牛人博客 codeplex IIS官网 IE11 Developer Jquery源码视频上 Jquery源码视频下 Jquery Bugs jquery.miaov.com 正则表达式 Jquery API 1.9 Service Broker Javascript Object中的方法讲解 Microsoft webcast 微信开发接口 ECMAScript5 Underscore Jquery Bugs SQL存储过程事务嵌套 官网SQL事务锁 2345天气插件 Json数据查看 C++ jquery-plugin-validate 博学谷(传智播客) Swift视频 IOS代码论坛 SWIFT设计模式 操作系统下载 AngularJS VueJS ASPNETCORE 前端题库 Node.js ASPNETCORE 腾讯课堂 SwiftUI SwiftUI疑问解答 ADO.NET SMO 数字化企业网 Unicode码查询 Redis使用文档 .NET 微服务:适用于容器化 .NET 应用程序的体系结构 .NETCore5.0微软官方文档 CSS3.0 在 ASP.NET Core 中配置 Windows 身份验证 Maven使用教程 Maven Repository Thymeleaf Thymeleaf中文CSDN Spring官方文档 Spring中文文档 SpringBoot SpringData SVG在线设计工具 SVG教程01 SVG教程02 fontawesome图标库 mybatis官网 mybatis-spring中文 mysql教程 python教程 python的scrapy教程01 python的scrapy教程02 VS开发python xpath教程 腾讯向量数据库教程 JSZip浏览器内存中创建文件与文件夹 axios的使用文档 SheetJS(JS操作excel)的使用文档

huaan011

 

混合线程同步构造

  定义:通过合并用户模式和内核模式的构造来构建的,称为混合线程同步构造(hybrid thread synchronization construct).在没有线程竞争的时候,混合构造提供了基于用户模式构造所具有的性能上的优势。在有多个线程同时竞争一个构造的时候,混合构造还使用基于内核模式的构造来提供不“自旋”的优势。
  由于在大多数应用程序中,线程都很少同时竞争一个构造,所以性能上的增强可以使你的应用程序表现得更出色。

  一个简单的混合锁:

  

internal sealed class SimpleHybridLock : IDisposable{
  // Int32由基元用户模式构造(Interlocked的方法)使用
 private Int32 m_waiters=0;
 // AutoResetEvent是基元内核模式构造
 private AutoResetEvent m_waitLock = new AutoResetEvent(false);
 public void Enter(){
        if(Interlocked.Increment(ref m_waiters)==1)   
        {
             return; //此时锁可自由使用,无竞争,直接返回
        } 
        //另一个线程正在等待。这代表一个竞争,因此阻塞这个线程
        m_waitLock.WaitOne();//这里产生较大的性能影响
        //WaitOne返回后,这个线程现在拥有了锁    
    }
  public void Leave(){
       if(Interlocked.Increment(ref m_waiters)==0)
       {
            return;//不存在需要唤醒的线程了,直接返回
        }
        //有其它线程正在阻塞,唤醒其中一个
        m_waitLock.Set();//这里产生较大的性能影响
    }
   public void Dispose(){
       m_waitLock.Dispose();
    }
}        

 SimpleHybridLock包含两个字段:一个 Int32,它将通过基元用户模式的构造来操作;以及一个AutoResetEvent,它是一个基于内核模式的构造.为了获得出色的性能,锁尽量使用Int32,尽量避免使用AutoResetEvent.只是构造一个SimpleHybridLock对象,就会导致AutoResetEvent的创建;相较于Int32字段所产生的开销,这会使性能造成较大的损失。

  SimpleHybridLock解释:

    调用Enter的第一个线程造成Interlocked.Increment在m_waiters字段上加1,使它的值变成1.这个线程发现以前有零个线程正在等待这个锁,所以线程从它的Enter调用中返回。值得欣赏的是,线程获得锁的速度是非常快的。现在如果另一个线程介入并调用Enter,这个线程将 m_waiters递增到2,发现锁在另一个线程那里。所以,这个线程会使用AutoResetEvent对象来调用WaitOne,从而阻塞自身。调用WaitOne造成线程的代码转换成内核模式的代码,这会对性能产生巨大影响。然而,线程现在会阻塞,不会因为在CPU上“自旋”而浪费CPU的时间。

    调用Leave方法时,会调用Interlocked.Decrement从m_waiters字段减1.如果m_waiters现在是0,表明没有其他线程在对Enter的调用中发生阻塞,调用Leave的线程可以直接返回。同样地,想象一下这有多快:离开一个锁意味着一个线程从一个Int32中减1,执行快速的if测试,然后返回!另一方面,如果调用Leave的线程发现m_waiters不为1,线程就知道现在存在一个竞争,另外至少有一个线程在内核中阻塞。这个线程必须唤醒一个(而且只能是一个)阻塞的线程。唤醒线程是通过在AutoResetEvent上调用Set来实现的。这会造成性能上的损失,因为线程必须转换成内核模式的代码,然后又转回来。但是,只有在发生竞争是,才会发生这种转换。当然,AutoResetEvent确保只有一个阻塞的线程被唤醒;在AutoResetEvent上阻塞的其他所有线程会继续阻塞,直到新的、解除了阻塞的线程最终调用Leave。

 

posted on 2014-03-05 15:18  华安  阅读(524)  评论(0编辑  收藏  举报

导航