c# - 看到很多 clr!CLRSemaphore::Wait in call stack

标签 c# multithreading debugging threadpool windbg

我们看到很多如下所示的调用堆栈,我可以知道什么条件\situation 会发生这种情况吗?

OS Thread Id: 0x48654 (559)
Current frame: ntdll!NtWaitForSingleObject+0xa
Child-SP         RetAddr          Caller, Callee
00000020a76cf480 00007fffd4ea1118 KERNELBASE!WaitForSingleObjectEx+0x94, calling ntdll!NtWaitForSingleObject
00000020a76cf520 00007fffce50ce66 clr!CLRSemaphore::Wait+0x8a, calling kernel32!WaitForSingleObjectEx
00000020a76cf5e0 00007fffce50d247 clr!ThreadpoolMgr::UnfairSemaphore::Wait+0x109, calling clr!CLRSemaphore::Wait
00000020a76cf620 00007fffce50d330 clr!ThreadpoolMgr::WorkerThreadStart+0x1b9, calling clr!ThreadpoolMgr::UnfairSemaphore::Wait
00000020a76cf6c0 00007fffce5de8b6 clr!Thread::intermediateThreadProc+0x7d
00000020a76cfb40 00007fffce5de89f clr!Thread::intermediateThreadProc+0x66, calling clr!_chkstk
00000020a76cfb80 00007fffd60613d2 kernel32!BaseThreadInitThunk+0x22
00000020a76cfbb0 00007fffd7be5454 ntdll!RtlUserThreadStart+0x34
OS Thread Id: 0x3bd4c (560)
Current frame: ntdll!NtWaitForSingleObject+0xa
Child-SP         RetAddr          Caller, Callee
00000020a774e910 00007fffd4ea1118 KERNELBASE!WaitForSingleObjectEx+0x94, calling ntdll!NtWaitForSingleObject
00000020a774e9b0 00007fffce50ce66 clr!CLRSemaphore::Wait+0x8a, calling kernel32!WaitForSingleObjectEx
00000020a774ea70 00007fffce50d247 clr!ThreadpoolMgr::UnfairSemaphore::Wait+0x109, calling clr!CLRSemaphore::Wait
00000020a774eab0 00007fffce50d330 clr!ThreadpoolMgr::WorkerThreadStart+0x1b9, calling clr!ThreadpoolMgr::UnfairSemaphore::Wait
00000020a774eb50 00007fffce5de8b6 clr!Thread::intermediateThreadProc+0x7d
00000020a774ec30 00007fffd7c00c75 ntdll!RtlpLowFragHeapAllocFromContext+0x355, calling ntdll!memset

最佳答案

正如 @Harry Johnston 所提到的在评论中,这些是线程池的工作线程,无关紧要。

以下示例可用于复制此类堆栈。它将创建 12 个线程池工作线程,当调试器中断时,它们都处于空闲状态,如您所见。

该代码基于微软的 Fibunacci threadpool example :

using System.Diagnostics;
using System.Threading;

public class Fibonacci
{
    public void ThreadPoolCallback(object threadContext)
    {
        FibOfN = Calculate(N);
        DoneEvent.Set();
    }

    public int Calculate(int n)
    {
        if (n <= 1) return n;
        return Calculate(n - 1) + Calculate(n - 2);
    }

    public int N { get; set; }
    public int FibOfN { get; private set; }
    public ManualResetEvent DoneEvent { get; set; }
}

public class ClrSemaphoreWaitDemo
{
    static void Main()
    {
        const int numberOfTasks = 12;
        var doneEvents = new ManualResetEvent[numberOfTasks];
        var fibArray = new Fibonacci[numberOfTasks];
        ThreadPool.SetMaxThreads(numberOfTasks, numberOfTasks);
        ThreadPool.SetMinThreads(numberOfTasks, numberOfTasks);

        for (int i = 0; i < numberOfTasks; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            fibArray[i] = new Fibonacci {N= 4, DoneEvent= doneEvents[i]};
            ThreadPool.QueueUserWorkItem(fibArray[i].ThreadPoolCallback, i);
        }

        WaitHandle.WaitAll(doneEvents);
        Debug.WriteLine("Now run .symfix; .reload; .loadby sos clr; !threads; !threads; !findstack clr!CLRSemaphore::Wait");
        Debugger.Break();
    }
}

当调试器中断时,运行以下命令:
.symfix; .reload; .loadby sos clr; !threads; !threads; !findstack clr!CLRSemaphore::Wait

关于c# - 看到很多 clr!CLRSemaphore::Wait in call stack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38908668/

相关文章:

c# - 如何在 ASP.net 自定义控件中处理 PostBack

c# elastic search nest 如何输出文档评分

multithreading - 如何将纤维传递给线程?

python - 从Pool.async_map返回第一个非零结果

java - Eclipse 调试器总是阻塞在 ThreadPoolExecutor 上,没有任何明显的异常,为什么?

c# - 如何从后台工作人员的外部类调用的方法调用表单上的方法?

c# - 在 IDialog 中使用 ILifetimeScope

python - 通过 Python 和 Eventlet 使用多核

.net - 生成非托管代码崩溃的转储?

python - 如何判断我的 python 脚本卡在哪里?