使用WinDbg —— .NET篇 (八)

来源:互联网 发布:读小说软件 编辑:程序博客网 时间:2024/05/16 13:40

7.2 Mutex, Semaphore EventWaitHandle

首先如果要避免非原子性的操作的读脏问题,就不免涉及到线程间的通信问题,这里所说的通信是指:一个线程在运行到某个地方通知其他的线程可以运行或者通知其他线程需要等待的通信,从而避免读脏问题,在Windows主要使用EventWaitHandle(奇迹般的找不到这个关键字的中文翻译)、互斥体(Mutex)、信号量(Semaphore)进行线程间的通信(这些对象也能用在进程间的通信)。在.NET中还实现了很多锁的封装,也能用于线程间的通信。首先说一说EventWaitHandleMutexSemaphore,在C#语言中这些都有都有对应的CSharp类,并且这些类都继承于WaitHandle类,而且这三个类实例化的对象都含有一个系统对象,对应的系统对象类型分别为EventMutantSemaphore,这三个类型具体的用法就不描述了。因为都对应着系统对象,所以在Windbg中可以通过托管对象找到对应的该系统对象所对应的句柄索引值,然后通过命令“!handle”命令打印出基本的系统对象信息。在讲解命令之前,先看如下代码:

using System;

using System.Threading;

 

namespace TestWaitHandle

{

   classProgram

    {

       staticMutex _mutex =newMutex(false);

       staticSemaphore _semaphore =newSemaphore(0,1);

       staticEventWaitHandle _eventWaitHandle =newEventWaitHandle(false,EventResetMode.AutoReset);

 

       staticvoid Main(string[] args)

        {

           newThread(Require).Start();

            _semaphore.WaitOne();

            _mutex.WaitOne();

            _eventWaitHandle.WaitOne();

            _mutex.Dispose();

            _semaphore.Dispose();

            _eventWaitHandle.Dispose();

           Console.WriteLine("Released");

           Console.ReadKey();

        }

 

       staticvoid Require()

        {

            _mutex.WaitOne();

           Console.WriteLine("Press any key to release all waiting handlers...");

           Console.ReadKey();

            _mutex.ReleaseMutex();

            _semaphore.Release();

            _eventWaitHandle.Set();

        }

    }

}

这段代码分别用了MutexSemaphore、和EventWaitHandle来实现线程间的通信。我首先展示怎么查看Mutex的对象信息:

0:007> !dumpheap -type System.Threading.Mutex

 Address       MT     Size

02422fdc 78dd0c0c       24    

0242302c 78dbb004       16    

0242303c 78dbb03c       28    

 

Statistics:

      MT    Count    TotalSize Class Name

78dbb004        1           16 System.Threading.Mutex+MutexCleanupInfo

78dd0c0c        1           24 System.Threading.Mutex

78dbb03c        1           28 System.Threading.Mutex+MutexTryCodeHelper

Total 3 objects

0:007> !do 02422fdc

Name:        System.Threading.Mutex

MethodTable: 78dd0c0c

EEClass:     78a1ab04

Size:        24(0x18) bytes

File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Fields:

      MT    Field   Offset                 Type VT     Attr    Value Name

78dddc14  4000577        4        System.Object  0 instance 00000000 __identity

78ddc04c  40018fc        c        System.IntPtr  1 instance      278 waitHandle

78ddb248  40018fd        8 ...es.SafeWaitHandle  0 instance 02423078 safeWaitHandle

78dd78f4  40018fe       10       System.Boolean  1 instance        1 hasThreadAffinity

78ddc04c  40018ff      e40        System.IntPtr  1   shared   static InvalidHandle

    >> Domain:Value  00b92198:ffffffff <<

78dd78f4  4001867      e33       System.Boolean  1   shared   static dummyBool

>> Domain:Value  00b92198:NotInit  <<

首先通过“!dumpheap-type”的命令找到Mutex对象的地址,然后打印出该对象对应的字段表格信息,在这个表格中可以看到粗体标出的部分,字段名为waitHandle,这是一个值类型,该值为278,这个值是指该Mutex对象封装的系统对象在系统句柄表中的索引,我们可以通过“!handle”打印出对应的信息:

0:007> !handle 278 8

Handle 278

  Object Specific Information

    Mutex is Owned

    Mutant Owner 19a0.20

在这里使用的命令中276为句柄索引值,后面紧跟着8,这个8是“!handle”的参数,表示打印出系统对象的信息信息。从打印出来的信息里面可以看到这个系统对象是Mutex类型,而且被进程ID0x19a0,线程ID0x20的线程所占有:

0:007> !threads

ThreadCount:      3

UnstartedThread:  0

BackgroundThread: 1

PendingThread:    0

DeadThread:       0

Hosted Runtime:   no

                                                                         Lock 

       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception

   0    1 1968 00bc9f80   202a020 Preemptive  0242320C:00000000 00b92198 0     MTA

   5    2  a00 00bd6858     2b220 Preemptive  00000000:00000000 00b92198 0     MTA (Finalizer)

   6    3   20 00bedbb8     2b020 Preemptive  024264A4:00000000 00b92198 1     MTA

可以看到这个0x20的线程是6号线程。对于SemaphoreEventWaitHandle,可以通过同样的方式找出详细信息:

0:007> !dumpheap -type System.Threading.Semaphore

 Address       MT     Size

0242308c 7a55f6d4       24    

 

Statistics:

      MT    Count    TotalSize Class Name

7a55f6d4        1           24 System.Threading.Semaphore

Total 1 objects

0:007> !do 0242308c

Name:        System.Threading.Semaphore

MethodTable: 7a55f6d4

EEClass:     7a34d010

Size:        24(0x18) bytes

File:        C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll

Fields:

      MT    Field   Offset                 Type VT     Attr    Value Name

78dddc14  4000577        4        System.Object  0 instance 00000000 __identity

78ddc04c  40018fc        c        System.IntPtr  1 instance      284 waitHandle

78ddb248  40018fd        8 ...es.SafeWaitHandle  0 instance 024230a4 safeWaitHandle

78dd78f4  40018fe       10       System.Boolean  1 instance        0 hasThreadAffinity

78ddc04c  40018ff      e40        System.IntPtr  1   shared   static InvalidHandle

    >> Domain:Value  00b92198:ffffffff <<

0:007> !handle 284  8

Handle 284

  Object Specific Information

    Semaphore Count 0

    Semaphore Limit 1

0:007> !dumpheap -type System.Threading.EventWaitHandle

 Address       MT     Size

024230b8 78ddb3f8       24    

 

Statistics:

      MT    Count    TotalSize Class Name

78ddb3f8        1           24 System.Threading.EventWaitHandle

Total 1 objects

0:007> !do 024230b8

Name:        System.Threading.EventWaitHandle

MethodTable: 78ddb3f8

EEClass:     78a1e348

Size:        24(0x18) bytes

File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Fields:

      MT    Field   Offset                 Type VT     Attr    Value Name

78dddc14  4000577        4        System.Object  0 instance 00000000 __identity

78ddc04c  40018fc        c        System.IntPtr  1 instance      288 waitHandle

78ddb248  40018fd        8 ...es.SafeWaitHandle  0 instance 024230d0 safeWaitHandle

78dd78f4  40018fe       10       System.Boolean  1 instance        0 hasThreadAffinity

78ddc04c  40018ff      e40        System.IntPtr  1   shared   static InvalidHandle

    >> Domain:Value  00b92198:ffffffff <<

0:007> !handle 288 8

Handle 288

  Object Specific Information

    Event Type Auto Reset

    Event is Waiting

 

0 0