使用Visual Studio 2015,在一个新的空C ++项目中,为控制台应用程序构建以下内容:
int main() {
return 0;
}
在返回时设置断点并在调试器中启动程序。在Windows 7上,从断点开始,该程序只有一个线程。但在Windows 10上,它有五个(!)线程:主线程和四个“工作线程”等待同步对象。
谁在启动线程池(或者我如何找到)?
答案 0 :(得分:25)
水晶球说调试> Windows> “线程”窗口在ntdll.dll!TppWorkerThread
处显示这些线程。请务必启用Microsoft Symbol Server以自行查看,使用工具>选项>调试>符号。
这也发生在VS2013中,所以它绝对不是由新的VS2015诊断功能引起的,@ Adam的猜测是不正确的。
TppWorkerThread()是线程池线程的入口点。当我使用Debug>设置断点时新断点>关于此功能的功能断点。我很幸运在第二个线程池线程开始执行时捕获第一个线程池线程的堆栈跟踪:
ntdll.dll!_NtOpenFile@24() Unknown
ntdll.dll!LdrpMapDllNtFileName() Unknown
ntdll.dll!LdrpMapDllSearchPath() Unknown
ntdll.dll!LdrpProcessWork() Unknown
ntdll.dll!_LdrpWorkCallback@12() Unknown
ntdll.dll!TppWorkpExecuteCallback() Unknown
ntdll.dll!TppWorkerThread() Unknown
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
> ntdll.dll!__RtlUserThreadStart@8() Unknown
显然,加载程序正在使用Windows 10上的线程池来加载DLL。这肯定是新的:)此时主线程也在加载器中执行,并发工作。
因此,Windows 10正在利用多个内核来更快地初始化进程。非常一个功能,而不是一个bug :))
答案 1 :(得分:3)
这是默认的线程池。 https://docs.microsoft.com/en-us/windows/desktop/procthread/thread-pools
每个进程都有一个默认的线程池。
答案 2 :(得分:-1)
这也使我陷入困境,所以我决定找到我的个人答案;就像另一位海报所说的那样,它有点像“水晶球”,但是...
可能的原因是您的其中一个线程之一:
在最新版本的Windows中执行此操作似乎会生成线程池,以方便等待对象(不知道为什么)。
这也可能是在您的主程序之前发生的,因为您有一些代码会导致创建一个全局范围的对象,然后在您甚至没有进入入口点之前就从代码开始(这甚至可能在Windows的某些标准库代码中) 10 SDK)。
对于任何想找出自己特定原因的人,您可以尝试以下方法:
class RunBeforeMain
{
public:
RunBeforeMain()
{
HMODULE hNtDll = (HMODULE)LoadLibrary(_T("ntdll.dll"));
FARPROC lpNeeded = GetProcAddress(hNtDll,"NtWaitForMultipleObjects");
DebugBreakPoint();
}
};
RunBeforeMain go;
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
}
运行此命令时,您将在lpNeeded中获取NtDll过程NtWaitForMultipleObjects的库加载位置,获取该地址并将其粘贴到反汇编视图窗口中,然后在第一行上放置一个断点。
现在继续运行您的解决方案。
警告:
希望这对某人有帮助:)
答案 3 :(得分:-3)
我知道这是一个 5 年前的问题,但 Microsoft 已经告诉您它使用“遥测”,并且您已经知道 Microsoft Visual Studio 2015 及更高版本向您的可执行文件中注入了一些您不允许的额外代码编辑。根据微软的说法,额外的代码不是你的事,你无法控制它,也不允许你看到它。你懂的。您选择使用 Visual Studio,并且您知道 Microsoft 已经告诉您他们这样做并且您已经接受了后果。微软已经告诉你它会这样做。如果 Microsoft 注入的代码与您自己的代码冲突,那么不要期望您自己的代码能够按您的意愿优先运行。同样,您已经知道这一点。
那些额外的线程来自 Microsoft,而不是来自您,除非您选择使用 Visual Studio 2015 及更高版本。
不必惊讶。微软已经公开告诉你这一点。
[不是]等待你使用的线程池。 Microsoft 已经告诉您,他们在 Visual Studio 2015 及更高版本中执行此操作。
Windows 10 [未] 利用多核来更快地初始化进程。 [这是] [Microsoft 遥测] 的一个功能,而不是一个错误 [但实际上将 Microsoft 注入的遥测代码注入到您的可执行文件中,而您没有任何控制。] :[(].
想阻止吗?其中一种方法是: 在非遥测嵌入式操作系统或没有“遥测”功能的旧版 Microsoft 操作系统上编写 C++11 程序;无需任何版本的 Microsoft Visual Studio 即可编译;使用此程序启动和快速子类化您当前被 Microsoft 程序感染的程序,然后停止子类程序启动的任何线程,然后将所有请求重定向到您的子类程序最初不打算使用的 dll。>
Microsoft 不是您的敌人,您选择做出然后忽略直至受伤的假设可能是您的敌人。