架构深渊

慢慢走进程序的深渊……关注领域驱动设计、测试驱动开发、设计模式、企业应用架构模式……积累技术细节,以设计架构为宗。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

看看C#中用lock关键实现同步的原理

Posted on 2008-09-27 23:05  chen eric  阅读(1926)  评论(3编辑  收藏  举报

[它山之石]看看C#中用lock关键实现同步的原理

我们知道C#的关键字都对应着.net Framework的类型,对象,比如string 对应String。那么“Lock”是如何对应的呢,似乎不能像string一样那么明显地找一个对应的东西。但是通过使用“ildasm”工具,察看.net生成的中间代码,很容易能发现lock的工作机制:调用了System.Threading.Monitor.Enter/Exit来实现同步互斥。看下面一段代码:

object someObject = new object();

. . .

private void button1_Click(object sender, EventArgs e)

{

    lock(someObject)

    {

        // Your code here

    }           }
利用
ildasm打开编译过的代码,下面是生成的IL(中间语言)的代码:

.method private hidebysig instance void button1_Click(object sender, class [mscorlib]System.EventArgs e) cil managed

{

 // Code size       29 (0x1d)

 .maxstack 2

 .locals init ([0] object CS$2$0000)

 IL_0000: nop

 IL_0001: ldarg.0

 IL_0002: ldfld      object WindowsApplication1.Form1::someObject

 IL_0007: dup

 IL_0008: stloc.0

 IL_0009: call       void [mscorlib]System.Threading.Monitor::Enter(object)

 IL_000e: nop

 .try

 {

    IL_000f: nop

    IL_0010: nop

    IL_0011: leave.s    IL_001b

 } // end .try

 finally

 {

    IL_0013: ldloc.0

    IL_0014: call       void [mscorlib]System.Threading.Monitor::Exit(object)

    IL_0019: nop

    IL_001a: endfinally

 } // end handler

 IL_001b: nop

 IL_001c: ret

} // end of method Form1::button1_Click

 然后再看看显示调用System.Threading.Monitor.Enter/Exit进行同步的代码:

private void button1_Click(object sender, EventArgs e)

{

    System.Threading.Monitor.Enter(someObject);

 

    try

    {

        // Your code here

    }

    finally

    {

        System.Threading.Monitor.Exit(someObject);

    }        }
察看它的IL:

.method private hidebysig instance void button1_Click(object sender, class [mscorlib]System.EventArgs e) cil managed

{

 // Code size       34 (0x22)

 .maxstack 1

 IL_0000: nop

 IL_0001: ldarg.0

 IL_0002: ldfld      object WindowsApplication1.Form1::someObject

 IL_0007: call       void [mscorlib]System.Threading.Monitor::Enter(object)

 IL_000c: nop

 .try

 {

    IL_000d: nop

    IL_000e: nop

    IL_000f: leave.s    IL_0020

  } // end .try

 finally

 {

    IL_0011: nop

    IL_0012: ldarg.0

    IL_0013: ldfld      object WindowsApplication1.Form1::someObject

    IL_0018: call       void [mscorlib]System.Threading.Monitor::Exit(object)

    IL_001d: nop

    IL_001e: nop

    IL_001f: endfinally

 } // end handler

 IL_0020: nop

 IL_0021: ret     } // end of method Form1::button1_Click
通过比较很容易发现这两段代码生成的中间语言代码几乎是一样的,至此我们应该能够很明白lcok的工作原理了。