使用WinDbg —— .NET篇 (八)
来源:互联网 发布:读小说软件 编辑:程序博客网 时间:2024/05/16 13:40
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
{
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();
}
}
}
这段代码分别用了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
- 使用WinDbg —— .NET篇 (八)
- 使用WinDbg —— .NET篇 (一)
- 使用WinDbg —— .NET篇 (二)
- 使用WinDbg —— .NET篇 (三)
- 使用WinDbg —— .NET篇 (四)
- 使用WinDbg —— .NET篇 (五)
- 使用WinDbg —— .NET篇 (六)
- 使用WinDbg —— .NET篇 (七)
- 使用WinDbg —— .NET篇 (九)
- 使用WinDbg —— .NET篇 (十)
- 使用WinDbg —— .NET篇 (十一)
- 使用WinDbg —— .NET篇 (十二)
- 使用WinDbg —— .NET篇 (十三)
- 使用Windbg 调试.Net程序
- 使用Windbg调试.Net应用程序
- 使用Windbg 调试.Net程序
- 快速入门:使用WINDBG调试.NET 程序
- WinDbg学习笔记八
- 《剑指offer》——二叉树的镜像
- android touch处理
- Macpro + python + opencv
- RecyclerView 解析(一)
- KNN分类算法实现By Java
- 使用WinDbg —— .NET篇 (八)
- java基础-深度克隆和浅克隆
- leetcode 13. Roman to Integer
- Android实现C语言写的系统
- UVALive 6091 并查集简单应用
- 函数定义为宏(以编译时间换空间)inline修饰的内联(内嵌)函数(空间换时间)
- 跟着沈毅学微电商(PHP):一
- 从最大似然到EM算法浅解
- 对学习java的心得体会1