.NET线程同步问题的调试方法

本文介绍了.NET线程同步问题的调试方法,包括lock statement、AutoResetEvent/ManualResetEvent、Mutex和Semaphore的使用。通过查看线程状态、调用栈和对象同步块,确定线程等待和死锁的原因。例如,通过!clrstack和!syncblk命令定位同步对象,找出等待线程和同步块索引,从而分析问题。
摘要由CSDN通过智能技术生成

问题介绍

.NET中线程同步经常用到以下方式,

线程同步经常遇到的问题有以下几种,

  • 等待 - 等待锁释放
  • 死锁 - 请求锁资源顺序不一致而造成互锁
  • 脏读 - 线程访问资源缺少同步机制保护

死锁也是等待,只是死锁的等待程序无法自解。



脏读一般用在数据库系统中的概念,即多个线程访问同一个资源过程中读与写同时进行。例如在循环遍历某个数组的时候抛出了异常报告正在遍历的数组被更改,Collection was modified; enumeration operation may not execute.

这类问题造成的原因主要是由于在写的过程中缺少排他锁,相应的解决方案可以考虑减少资源的可见度,把资源的访问控制在有限的几个特定的方法中,然后在这些特定的方法上面相应的读写处加锁来避免脏读发生。


调试方法


lock statement

调试等待问题首先还是要先确定线程对象,弄清楚谁在等谁?下面是一个使用lock statement (Monitor class)的简单线程等待的例子,3号线程在Sleep,4号线程在等待。根据调用栈我们可以知道四号线程是在调用Monitor.Enter()方法。

   3  Id: 27fc.7f0 Suspend: 1 Teb: 000007f5`ffae6000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`1b9fea28 000007f8`0e6b11f2 ntdll!NtDelayExecution+0xa
00000000`1b9fea30 000007ff`f803369d KERNELBASE!SleepEx+0xaa
00000000`1b9fead0 000007ff`f7c2e7fd mscorwks!EESleepEx+0x2d
00000000`1b9feb50 000007ff`f81f0769 mscorwks!Thread::UserSleep+0x71
00000000`1b9febb0 000007ff`98500486 mscorwks!ThreadNative::Sleep+0xf9
00000000`1b9fed60 000007ff`f30d2bdb Synchronization!Synchronization.Program.ThreadProc()+0x106
00000000`1b9fee00 000007ff`f316a9bd mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x9b
00000000`1b9fee50 000007ff`f7dbd552 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart()+0x4d
00000000`1b9feea0 000007ff`f7cfa283 mscorwks!CallDescrWorker+0x82
00000000`1b9feef0 000007ff`f819c7af mscorwks!CallDescrWorkerWithHandler+0xd3
00000000`1b9fef90 000007ff`f7be4415 mscorwks!MethodDesc::CallDescr+0x2af
00000000`1b9ff1d0 000007ff`f7d3cda4 mscorwks!ThreadNative::KickOffThread_Worker+0x191
00000000`1b9ff4f0 000007ff`f7d23721 mscorwks!ManagedThreadBase_DispatchInner+0x2c
00000000`1b9ff540 000007ff`f7c1fc59 mscorwks!ManagedThreadBase_DispatchMiddle+0x9d
00000000`1b9ff610 000007ff`f7d7c949 mscorwks!ManagedThreadBase_DispatchOuter+0x31
00000000`1b9ff650 000007ff`f7d472d3 mscorwks!ManagedThreadBase_FullTransitionWithAD+0x35
00000000`1b9ff6b0 000007ff`f7d3f3a4 mscorwks!ThreadNative::KickOffThread+0xd3
00000000`1b9ff790 000007f8`0f16167e mscorwks!Thread::intermediateThreadProc+0x78
00000000`1b9ff8e0 000007f8`116d3501 KERNEL32!BaseThreadInitThunk+0x1a
00000000`1b9ff910 00000000`00000000 ntdll!RtlUserThreadStart+0x21

   4  Id: 27fc.2634 Suspend: 1 Teb: 000007f5`ffae4000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`1bafe5c8 000007f8`0e6b12c6 ntdll!ZwWaitForMultipleObjects+0xa
00000000`1bafe5d0 000007ff`f7c1e7f9 KERNELBASE!WaitForMultipleObjectsEx+0xe5
00000000`1bafe8b0 000007ff`f7c231e1 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0xc1
00000000`1bafe950 000007ff`f7d203d5 mscorwks!Thread::DoAppropriateAptStateWait+0x41
00000000`1bafe9b0 000007ff`f7c3e94c mscorwks!Thread::DoAppropriateWaitWorker+0x191
00000000`1bafeab0 000007ff`f7c7d16a mscorwks!Thread::DoAppropriateWait+0x5c
00000000`1bafeb20 000007ff`f7c00fd1 mscorwks!CLREvent::WaitEx+0xbe
00000000`1bafebd0 000007ff`f7d4e002 mscorwks!AwareLock::EnterEpilog+0xc9
00000000`1bafeca0 000007ff`f815a815 mscorwks!AwareLock::Enter+0x72
00000000`1bafecd0 000007ff`98500427 mscorwks!JIT_MonEnterWorker_Portable+0xf5
00000000`1bafeea0 000007ff`f30d2bdb Synchronization!Synchronization.Program.ThreadProc()+0xa7
00000000`1bafef40 000007ff`f316a9bd mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x9b
00000000`1bafef90 000007ff`f7dbd

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值