.NET线程如何等待不属于任何线程的syncblk?

我的应用程序中有一个崩溃转储显示了一堆等待syncblk的线程,而syncblk显示它没有拥有线程。 怎么可能? 我试图重现测试应用程序中的症状,我无法弄清楚产生该结果可能发生什么….拥有拥有线程退出或死亡而不释放syncblk仍显示为拥有该对象,只是线程是“XXX”….我已经测试使用完全管理的优雅退出和硬线程终止通过pinvoke ….我测试了一堆不同的等待组合没有脉冲,不匹配进入和退出…什么都没有产生一个syncblk阻止线程,并没有显示所有者…..我的想法已经用完了

这是我正在尝试复制的crashdump的输出:(注意索引#1236)

0:000> !syncblk Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 784 0000000004f12eb0 3 1 000000000508a460 32a8 68 00000001a0a20510 966 0000000004f06928 1 1 00000000052c5da0 2380 114 00000001df3080f8 1085 0000000004f23088 1 1 00000000052c8080 496c 120 00000001a0325238 1144 0000000005160d20 1 1 00000000050968b0 d74 56 00000000ff61b570 1151 0000000004f0c2c8 1 1 000000000508d8b0 3f64 77 000000017f66dc20 1236 0000000004f0b4f8 16 0 0000000000000000 none 000000019f1ec5d8 1261 0000000004f0ffe8 1 1 0000000008f18fc0 446c 94 000000013f8e70b0 1306 0000000004f0e918 1 1 00000000052c91f0 406c 123 000000011f5936f8 1318 0000000004f0e528 3 1 0000000008f1d580 24d8 106 000000015fc73f28 1329 0000000004f0cc58 1 1 0000000005095740 2fbc 53 000000011f36d320 1332 0000000004f15b38 1 1 0000000008f16710 3804 87 000000019f964728 1387 0000000004f22350 1 1 0000000008f18420 5180 92 00000001a008ab08 1515 0000000004f1d5d0 1 1 00000000052c4c30 2b5c 111 00000000ffd3c068 1594 0000000004f19bc0 1 1 000000000508ea20 188c 80 000000012012c538 1660 0000000004f13608 1 1 00000000050892f0 32fc 65 00000001df800940 1682 00000000051608a0 1 1 000000000508c740 1d58 74 00000001bfa03d20 1746 0000000004f14e88 1 1 0000000008f1c9e0 e88 104 000000015f6fcd10 1883 0000000004f19938 1 1 0000000005092e90 27c4 46 00000000ff76d2b0 1886 0000000004f1b760 1 1 0000000008f19b60 2dd4 96 000000019fc07030 2036 0000000004f1ae10 1 1 0000000008f1be40 4f58 102 00000001dfcb9da8 2042 0000000004f12e68 1 1 00000000052c8c20 2300 122 000000015f6aaa98 2049 0000000004f1cda0 1 1 00000000052c9d90 1948 126 00000001df6fd688 2153 0000000004f16d88 1 1 0000000005094ba0 3f04 51 00000000ff677eb8 2262 0000000004f13de8 3 1 00000000052ca360 6fc 127 000000011fd7a450 2358 00000000050fc390 1 1 0000000009221280 3ca0 130 0000000120055ca0 ----------------------------- Total 2553 CCW 3 RCW 2 ComClassFactory 0 Free 1212 

SyncBlock 000000019f1ec5d8是没有所有者的。 也是唯一一个具有偶数MonitorHeld计数的人。 由于MonitorHeld 为所有者增加1,每个服务员增加2,我的猜测是这是在转储之前释放的资源,并且还没有授予新的所有者。 不公平的资源在发布时向所有服务员发出信号并且服务员急于获得它(这种不公平的行为避免了车队锁定)。 在服务员安排和运行之前,第一个服务员抓住资源,就没有所有者。

另请参阅免费关键部分的高服务员计数可能表示锁定车队 :

如果你正在调试应用程序中的性能问题,你可能会遇到一个非常奇怪状态的关键部分:很multithreading都在等待它,但是没有人拥有它!

这个状态意味着临界区的前一个所有者刚刚退出它并发出一个等待线程来接受它,但该线程还没有机会运行

你描述的可能有几个原因:

  • 拥有线程变得不稳定,有一些讨厌的访问冲突
  • 使用OutOfMemoryExceptions,拥有的线程变得不稳定
  • 系统的某些部分(如驾驶员……)造成了一种奇怪的情况
  • 某些使用本机代码的第三方库导致进程变得不稳定
  • 框架的一些重要部分(如GC /内存管理/线程管理)在一些重要操作的中间变得不稳定和/或死亡

以上任何一个都难以重现……

有关syncblk的精彩摘要,请参阅http://blogs.msdn.com/b/tess/archive/2006/01/09/a-hang-scenario-locks-and-critical-sections.aspx

可能性1:清除syncblk,16个线程中的下一个将在再次安排时立即获取它。 可能性2:你有腐败的记忆。