您的位置:首页 > 其它

使用WinDbg —— .NET篇 (八)

2016-05-28 20:18 309 查看
7.2 Mutex, Semaphore 与
EventWaitHandle

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

using System;
using System.Threading;

namespace TestWaitHandle
{

class
Program
{

static
Mutex _mutex =
new
Mutex(false);

static
Semaphore _semaphore =
new
Semaphore(0,1);

static
EventWaitHandle _eventWaitHandle =
new
EventWaitHandle(false,
EventResetMode.AutoReset);

static
void Main(string[]
args)
{

new
Thread(Require).Start();
_semaphore.WaitOne();
_mutex.WaitOne();
_eventWaitHandle.WaitOne();
_mutex.Dispose();
_semaphore.Dispose();
_eventWaitHandle.Dispose();

Console.WriteLine("Released");

Console.ReadKey();
}

static
void Require()
{
_mutex.WaitOne();

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

Console.ReadKey();
_mutex.ReleaseMutex();
_semaphore.Release();
_eventWaitHandle.Set();
}
}
}
这段代码分别用了Mutex、Semaphore、和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类型,而且被进程ID为0x19a0,线程ID为0x20的线程所占有:

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号线程。对于Semaphore和EventWaitHandle,可以通过同样的方式找出详细信息:

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: