c# - 在 Process Explorer 中调试 RtlUserThreadStart

标签 c# multithreading process-explorer

我有一个基于 3.5 构建的多线程 wpf 应用程序。当我通过 Process Explorer 查看正在运行的线程时,我看到 8 个线程都具有相同的起始地址 ntdll.dll!RtlUserThreadStart,并且所有八个线程的 CPU 值都在 3-6+ 之间,并且具有高循环增量。我无法弄清楚这些线程在做什么。它总是相同的线程。它永远不会在应用程序的同一实例中发生变化。当我同时调试我的应用程序并暂停调试器时,所有这些线程都显示一行用于堆栈 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     

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

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

或:

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

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

最佳答案

您的问题记录不足,但合理的猜测是您似乎使用了 PPL 库。它保留了一个线程池来完成并行作业。毫无疑问,您会看到高 CPU 周期计数,因为这些线程确实在执行您要求它们执行的工作。

与典型的线程池一样,PPL 保留这些线程以供下一个作业执行,这就是为什么您会看到它们等待 WaitForWork()。由于缺少调试符号, native 堆栈跟踪是垃圾。 RtlUserThreadStart 是一个 Windows 函数,您将始终在非托管堆栈跟踪中看到它,这就是线程启动的方式。

这是完全正常的。唯一值得注意的其他信息是 this answer由 Microsoft 员工发布:

The concurrency runtime caches threads for later re-use. They are released only when all the concurrency runtime schedulers have been shutdown. (Typically, there is just a single default scheduler in the process). A scheduler is shutdown when all the external threads that queued work to it has exited. So if the main thread scheduled work (by calling parallel_for from main() say) then the default scheduler would be deleted only on process shutdown.

There is an upper limit on the number of cached threads. It is rougly 4 times the number of cores on the machine (though there are some other factors affecting the threshold like the stack size option in scheduler policies).

关于c# - 在 Process Explorer 中调试 RtlUserThreadStart,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11235279/

相关文章:

multithreading - 在 Clozure Common Lisp 中生成多个进程来处理许多基于套接字的连接

java - 线程notifyAll()

c# - 在 Xamarin 中使用 ZeroMQ

java - 使用外部类锁获取内部类锁?

c# - 在 native 命名管道和 System.IO 命名管道之间发送多条消息

azure - 获取有关 Azure 文件共享文件句柄的详细信息 - Get-AzStorageFileHandle

.net - 在 Visual Studio 调试 session 期间查找当前目录?

c++ - 查找启动进程的命令行选项

c# - 从远程计算机简单绑定(bind)到 AD-LDS 失败

c# - 公共(public)变量不可访问