With Visual Studio 2015, in a new, empty C++ project, build the following for Console application:
int main() {
return 0;
}
Set a break point on the return and launch the program in the debugger. On Windows 7, as of the break point, this program has only one thread. But on Windows 10, it has five(!) threads: the main thread and four "worker threads" waiting on a synchronization object.
Who's starting up the thread pool (or how do I find out)?
Crystal ball says that the Debug > Windows > Threads window shows these threads at ntdll.dll!TppWorkerThread
. Be sure to enable the Microsoft Symbol Server to see this yourself, use Tools > Options > Debugging > Symbols.
This also happens in VS2013 so it is most definitely not caused by the new VS2015 diagnostic features, @Adam's guess cannot be correct.
TppWorkerThread() is the entrypoint for a thread-pool thread. When I set a breakpoint with Debug > New Breakpoint > Function Breakpoint on this function. I got lucky to capture this stack trace for the 1st threadpool thread when the 2nd threadpool thread started executing:
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
Clearly the loader is using the threadpool on Windows 10 to load DLLs. That's certainly new :) At this point the main thread is also executing in the loader, concurrency at work.
So Windows 10 is taking advantage of multiple cores to get the process initialized faster. Very much a feature, not a bug :)