在VS中进行调试时,请勿为ThreadPool中的线程命名

在2017年的某个时候,在VS中进行调试期间,项目的性能下降了约80%,从而将游戏变成了各种异步帧的集合。庆祝活动的罪魁祸首是池中的函数SetThreadName。谁不熟悉-ThreadPool是一种管理器,负责并行执行同一代码。例如,可以分配周期。其本质是创建多个线程(每个核心1个工作线程),并在工作完成后转移以等待/删除。

SetThreadName看起来像这样:

void SetThreadName(DWORD dwThreadID, const char* threadName) {
    THREADNAME_INFO info;
    info.dwType = 0x1000;
    info.szName = threadName;
    info.dwThreadID = dwThreadID;
    info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
    __try{
        RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
    }
    __except (EXCEPTION_EXECUTE_HANDLER){
    }
#pragma warning(pop)
}

在新的WinSDK中,可以用SetThreadDescription替换具有RaiseException的代码,最终可以节省情况。因为 RaiseException是一个相当慢的操作。

有几种最佳的退出情况:

  1. 原则上不要给工人起名字。
  2. 仅在Internet上进行捐赠并保持流量处于等待状态。加入正在运行的进程时,此方法不好-我们将不再识别名称。
  3. 工人没有被摧毁。如果先前已禁用每个任务,则检查每个任务是否存在已连接的调试器。IsDebuggerPresent

All Articles