新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → C# 中 lock 关键字的实现 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3954 个阅读者  浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: C# 中 lock 关键字的实现 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     admin 帅哥哟,离线,有人找我吗?
      
      
      
      威望:9
      头衔:W3China站长
      等级:计算机硕士学位(管理员)
      文章:5255
      积分:18407
      门派:W3CHINA.ORG
      注册:2003/10/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给admin发送一个短消息 把admin加入好友 查看admin的个人资料 搜索admin在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给admin  访问admin的主页 引用回复这个贴子 回复这个贴子 查看admin的博客楼主
    发贴心情 C# 中 lock 关键字的实现


    发信人: flier (小海 [寻找风车中]), 信区: DotNET
    标  题: C# 中 lock 关键字的实现
    发信站: BBS 水木清华站 (Wed Feb 25 00:24:01 2004), 转信

    http://www.blogcn.com/user8/flier_lu/main.asp?id=1256525

    C# 中 lock 关键字的实现

        刚刚在这篇文章 《How is lock keyword of C# implemented? 》中看到MS内部关于C#的lock关键字实现的一个讨论。

    以下为引用:

    Subject: RE: How is lock keyword of C# implemented?

    At the core, it’s typically one ?lock cmpxchg“ instruction (for x86) for entry, and one for exit, plus a couple dozen other instructions, all in user mode. The lock prefix is replaced with a nop on uniprocessor machines.

    The “lock cmpxchg” instruction basically stores the locking thread’s id in the object header, so another thread that tries to lock the same object can see that it’s already locked.

    The actual implementation is a lot more complicated, of course – we use the object header for other purposes, for example, so this must be detected and dealt with, plus when a thread leaves the lock, we must detect whether other threads are waiting and so on…

    Thanks

      



        回想起前两天分析过的临界区实现,就顺便看了看rotor这方面的实现代码,发现和Windows中临界区的实现思路基本上相同。
        在rotor中,每个引用对象内部实现是一个Object对象(sscli\clr\src\vm\object.h:126)的实例。而对象同步机制的实现,则是通过和Object对象绑定的ObjHeader对象(sscli\clr\src\vm\syncblk.h:539)中的SyncBlock结构完成的。这种实现思路跟Delphi中的VMT的实现很相似,rotor中Object对象指针的-4偏移处存储绑定的ObjHeader对象,Delphi则在负偏移处保存VMT表。

    以下为引用:

    class Object
    {
      //...
       
      // Access the ObjHeader which is at a negative offset on the object (because of
      // cache lines)
      ObjHeader   *GetHeader()
      {
          return ((ObjHeader *) this) - 1;
      }

      // retrieve or allocate a sync block for this object
      SyncBlock *GetSyncBlock()
      {
          return GetHeader()->GetSyncBlock();
      }
      
      //...
    };
      


         
        ObjHeader::GetSyncBlock(syncblk.cpp:1206)方法从缓冲区获取或者创建新的SyncBlock对象。SyncBlock对象则是一个使用lazily created策略的可缓存结构,调用其Monitor完成对象的实际锁定工作。

    以下为引用:


    // this is a lazily created additional block for an object which contains
    // synchronzation information and other "kitchen sink" data

    class SyncBlock
    {
      //...
       
      AwareLock  m_Monitor;                    // the actual monitor

      void EnterMonitor()
      {
          m_Monitor.Enter();
      }
         
      //...
    };
      


         
        AwareLock类型是一个很类似临界区的轻量级同步对象,其Enter(syncblk.cpp:1413)方法使用FastInterlockCompareExchange函数尝试锁定此Monitor。如果无法锁定则判断此Monitor的所有者线程是否是当前线程:是则调用线程嵌套锁定函数;否则等待此对象锁定状态的改变。

    以下为引用:

        Thread  *pCurThread = GetThread();

        for (;;) {

            // Read existing lock state.
            LONG state = m_MonitorHeld;

            if (state == 0) {

                // Common case: lock not held, no waiters. Attempt to acquire lock by
                // switching lock bit.
                if (FastInterlockCompareExchange((LONG*)&m_MonitorHeld, 1, 0) == 0)
                    break;

            } else {

                // It's possible to get here with waiters but no lock held, but in this
                // case a signal is about to be fired which will wake up a waiter. So
                // for fairness sake we should wait too.
                // Check first for recursive lock attempts on the same thread.
                if (m_HoldingThread == pCurThread)
                    goto Recursion;

                // Attempt to increment this count of waiters then goto contention
                // handling code.
                if (FastInterlockCompareExchange((LONG*)&m_MonitorHeld, state + 2, state) == state)
                    goto MustWait;
            }

        }  
      


         
        可以看到这儿的实现思路和临界区的实现基本上相同。
        FastInterlockCompareExchange函数(util.hpp:66)则是MS那个讨论里面提到的lock cmpxchg指令的调用之处。此函数根据编译时选项,被替换成CompareExchangeUP/CompareExchangeMP两个函数分别处理单/多处理器情况。可以参考vm\i386\cgenx86.cpp中的InitFastInterlockOps函数(cgenx86.cpp:2106)实现。在386平台上,这两个函数完全由汇编语言实现(i386\asmhelpers.asm:366, 440)。

    以下为引用:

    CmpXchgOps      FastInterlockCompareExchange = (CmpXchgOps)CompareExchangeUP;

    // Adjust the generic interlocked operations for any platform specific ones we
    // might have.
    void InitFastInterlockOps()
    {
      _ASSERTE(g_SystemInfo.dwNumberOfProcessors != 0);

      if (g_SystemInfo.dwNumberOfProcessors != 1)
      {
        //...

        FastInterlockCompareExchange = (CmpXchgOps)CompareExchangeMP;

        //...
      }
    }
      




    以下为引用:

    FASTCALL_FUNC CompareExchangeUP,12
    _ASSERT_ALIGNED_4_X86 ecx
    mov eax, [esp+4] ; Comparand
    cmpxchg [ecx], edx
    retn 4 ; result in EAX
    FASTCALL_ENDFUNC CompareExchangeUP

    FASTCALL_FUNC CompareExchangeMP,12
            _ASSERT_ALIGNED_4_X86 ecx
    mov eax, [esp+4] ; Comparand
      lock  cmpxchg [ecx], edx
    retn 4 ; result in EAX
    FASTCALL_ENDFUNC CompareExchangeMP
      



        值得注意的是那个讨论里面提到“The lock prefix is replaced with a nop on uniprocessor machines”,据rain的分析,NT核心部分的DLL也做了类似的优化。
    --
    .    生命的意义在于   /\   ____\ /\_ \   /\_\    http://flier_lu.blogone.net.                            .  
    .        希望         \ \  \___/_\/\ \   \/_/__     __    _ _★              .  
    .        工作          \ \   ____\\ \ \    /\  \  /'__`\ /\`'_\              .  
    .      爱你的人         \ \  \___/ \ \ \___\ \  \/\ __// \ \ \/              .  
    .     和你爱的人         \ \___\    \ \_____\ \__\ \____\ \ \_\              .  
    .        ……             \/___/     \/_____/\/__/\/____/  \/_/ @nsfocus.com.  


    ※ 来源:·BBS 水木清华站 smth.org·[FROM: 211.167.254.*]
    上一篇
    返回上一页
    回到目录
    回到页首
    下一篇


       收藏   分享  
    顶(0)
      





    关闭广告显示

    ----------------------------------------------

    -----------------------------------------------

    第十二章第一节《用ROR创建面向资源的服务》
    第十二章第二节《用Restlet创建面向资源的服务》
    第三章《REST式服务有什么不同》
    InfoQ SOA首席编辑胡键评《RESTful Web Services中文版》
    [InfoQ文章]解答有关REST的十点疑惑

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/11/9 2:26:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给Google AdSense  访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2025/7/16 17:24:43

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms