在Process Explorer中调试RtlUserThreadStart

Ben*_*Ben 4 c# multithreading process-explorer

我有一个基于3.5的多线程wpf应用程序.当我通过Process Explorer查看正在运行的线程时,我看到8个线程都具有相同的起始地址,ntdll.dll!RtlUserThreadStart,并且所有8个线程的CPU值均为3-6 +且具有高的Cycles Delta.我无法弄清楚这些线程在做什么.它始终是相同的线程.它永远不会在应用程序的同一个实例中发生变化.当我同时调试我的应用程序并暂停调试器时,所有这些线程都显示堆栈的单行,System.Threading.ConcurrencyScheduler.Scheduler.WaitForWork()或System.Threading.Monitor.Wait().

我启用了Visual Studio的符号文件,我在这些线程上看到了以下堆栈:

System.Threading.Monitor.Wait() Normal
mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout) + 0x19     bytes
System.Threading.dll!System.Threading.ConcurrencyScheduler.Scheduler.WaitForWork() + 0xd0 bytes  
System.Threading.dll!System.Threading.ConcurrencyScheduler.InternalContext.Dispatch() + 0x74a bytes
System.Threading.dll!System.Threading.ConcurrencyScheduler.ThreadInternalContext.ThreadStartBridge(System.IntPtr dummy) + 0x9f bytes     
Run Code Online (Sandbox Code Playgroud)

当我查看进程监视器中线程上提供的堆栈时,我看到以下示例:

0  ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
1  ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
2  ntoskrnl.exe!KeWaitForSingleObject+0x19f
3  ntoskrnl.exe!_misaligned_access+0xba4
4  ntoskrnl.exe!_misaligned_access+0x1821
5  ntoskrnl.exe!_misaligned_access+0x1a97
6  mscorwks.dll!InitializeFusion+0x990b
7  mscorwks.dll!DeleteShadowCache+0x31ef
Run Code Online (Sandbox Code Playgroud)

要么:

0  ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
1  ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
2  ntoskrnl.exe!KeWaitForSingleObject+0x19f
3  ntoskrnl.exe!_misaligned_access+0xba4
4  ntoskrnl.exe!_misaligned_access+0x1821
5  ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x93d
6  ntoskrnl.exe!KeWaitForMultipleObjects+0x26a
7  ntoskrnl.exe!NtWaitForSingleObject+0x41f
8  ntoskrnl.exe!NtWaitForSingleObject+0x78e
9  ntoskrnl.exe!KeSynchronizeExecution+0x3a23
10 ntdll.dll!ZwWaitForMultipleObjects+0xa
11 KERNELBASE.dll!GetCurrentProcess+0x40
12 KERNEL32.dll!WaitForMultipleObjectsEx+0xb3
13 mscorwks.dll!CreateApplicationContext+0x10499
14 mscorwks.dll!CreateApplicationContext+0xbc41
15 mscorwks.dll!StrongNameFreeBuffer+0xc54d
16 mscorwks.dll!StrongNameFreeBuffer+0x2ac48
17 mscorwks.dll!StrongNameTokenFromPublicKey+0x1a5ea
18 mscorwks.dll!CopyPDBs+0x17362
19 mscorwks.dll!CorExitProcess+0x3dc9
20 mscorwks.dll!TranslateSecurityAttributes+0x547f
21 mscorlib.ni.dll+0x8e6bc9
Run Code Online (Sandbox Code Playgroud)

作为此项目的附加说明.我的电脑是一个有4核的单CPU.当我们在具有4个内核的双CPU上运行相同的应用程序时,我们看到这个线程数从8到16.

Han*_*ant 6

您的问题严重缺乏记录,但合理的猜测是您似乎使用了PPL库.这样可以保留一组线程来完成并行作业.毫无疑问,你会看到高cpu周期数,因为这些线程确实正在完成你要求他们做的工作.

与线程池一样,PPL会保留这些线程以便下一个工作要做,这就是为什么你看到它们等待WaitForWork().由于缺少调试符号,本机堆栈跟踪是垃圾.RtlUserThreadStart是一个Windows函数,你总是会在非托管堆栈跟踪中看到它,这就是线程的启动方式.

这完全正常.值得注意的唯一其他信息是微软员工发布的答案:

并发运行时缓存线程以供以后重用.只有在所有并发运行时调度程序都已关闭时才会释放它们.(通常,流程中只有一个默认调度程序).当排队的所有外部线程都退出时,调度程序将关闭.因此,如果主线程调度工作(通过从main()调用parallel_for说),那么只有在进程关闭时才会删除默认调度程序.

缓存线程的数量有一个上限.它是机器上核心数量的4倍(尽管还有一些其他因素影响阈值,如调度程序策略中的堆栈大小选项).