混合线程同步构造

  定义:通过合并用户模式和内核模式的构造来构建的,称为混合线程同步构造(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。

 

转载于:https://www.cnblogs.com/huaan011/p/3582549.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值