【发布时间】:2020-06-29 09:23:33
【问题描述】:
Why does Windows 10 start extra threads in my program?
让我们看一个简单的代码,
class AA
{
...
};
AA& getAA(){
static AA aa;
return aa;
}
class BB
{
public: BB() { getAA(); ... }
...
};
thread_local BB bb;
我添加了更多我遇到的信息。
。 用这个简单的代码,我重写了调用栈。
偶尔会在 0x00007FFB0B1272A6(ntdll.dll) 处引发异常。 访问冲突写入位置 0x000000024。 g_tss_mutex 的成员除 LockCount 为 6 和 LockSemaphore 为 0xffffffffffffffff 外,均为零。 该函数是 _Init_thread_lock() 并且它正在调用 EnterCriticalSection(&g_tss_mutex); 工作线程 ntdll.dll 线程抛出此异常。 调用堆栈是。
ntdll.dll!00007ffb0b1272a6()
ntdll.dll!00007ffb0b13b5f6()
ntdll.dll!00007ffb0b13b440()
_init_thread_lock()
_Init_thread_header(int *pOnce)
getAA()
BB::BB()
`dynamic initializer for 'bb'()
主线程的调用栈是
_should_initialize_environment()
pre_c_initialization()
ucrtbased.dll!00007ffe9c1a4ab9
__scrt_common_main_seh()
__scrt_common_main()
WinMainCrtStartup()
....
Windows 10 线程池的Loader Threads 尝试初始化thread_local bb。但是如果加载器线程在进程的主线程不调用 _scrt_initialize_thread_safe_statics_platform_specific() 来调用 gerentee 静态魔法之前调用 bb 的构造函数。 https://docs.microsoft.com/en-us/cpp/build/reference/zc-threadsafeinit-thread-safe-local-static-initialization?view=vs-2019
我遇到了这种情况。我该怎么做才能解决这个问题。
【问题讨论】:
-
我无法理解“但是如果加载程序线程...”这句话——你能澄清一下吗?
-
对不起,我不明白这个问题。你能改写一下吗?
-
@tenfour LoaderThreads 表示ntdll为加载pararell库创建的线程。
-
@AsteroidsWithWings 抱歉。为了支持初始化静态局部变量的线程安全,调用了_scrt_initialize_thread_safe_statics_platform_specific()。因此,静态局部变量(
getAA()中的aa)的任何初始化都应该在该函数调用之后发生。但是,为了初始化 ntdll 的工作线程,在调用该函数之前调用 tls_init() 函数。此时,__bb正在初始化,结果调用了“getAA()”中aa的构造函数。 -
@walnut 对我的错误感到抱歉。我重写了代码。
__aa应该是__bb,__bb应该是aaingetAA()。
标签: c++ multithreading winapi threadpool ntdll