不使用_beginthread并不会导致内存泄漏
RLib 2016-08-15 01:55:55 使用/MT, /MTd编译, 测试环境vs2015 update3.
线程使用RtlCreateUserThread创建, 通过跟踪输出发现, 并没有如网传那样, 在不使用_beginthread/ex创建的线程中使用部分CRT函数会导致内存泄漏, 或许是高版本CRT修复了这个问题, 总之没有复现.
CRT 运行时初始化的大概流程, 首先分配fls(纤程局部存储), fls每个模块各自都会和只会初始化一次, 由加载该模块的线程在DLLMain/WinMain/main前完成, fls存储PTD(per thread data)结构指针, PTD的初始化有三种途径, 一种是在__acrt_initialize_ptd中分配完fls时(也就是模块加载时), 另一种是进程中加载了CRT支持的DLL(即DLL_THREAD_ATTACH时), 最后一种则是线程第一次调用CRT函数(内部调用__acrt_getptd/_noexit)时, 这些保证了不管线程何时创建都能正确使用CRT(包括signal, 这点尚存疑问, 但通过源码来看并无失败的道理).
而PTD的销毁则是在FlsAlloc时指定的回调destroy_fls中的被指定的, 在线程ExitThread之后会被触发, 从而并不存在内存泄漏问题.
FlsAlloc 5 Main Thread
construct 0x0000029d735d0680 {_pxcptacttab=0x00007ffcd149a360 {RLib_x64d.dll!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} Main Thread
FlsAlloc 7 Main Thread
construct 0x0000029d735d6810 {_pxcptacttab=0x00007ff71e8cac50 {crt_x64d.exe!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} Main Thread
construct 0x0000029d735dbb80 {_pxcptacttab=0x00007ffcd149a360 {RLib_x64d.dll!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} RLib_x64d.dll!System::Threading::Thread::__threadProcWrapper()
construct 0x0000029d735dd770 {_pxcptacttab=0x00007ff71e8cac50 {crt_x64d.exe!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} RLib_x64d.dll!System::Threading::Thread::__threadProcWrapper()
destroy 0x0000029d735dbb80 {_pxcptacttab=0x00007ffcd149a360 {RLib_x64d.dll!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} RLib_x64d.dll!System::Threading::Thread::__threadProcWrapper()
destroy 0x0000029d735dd770 {_pxcptacttab=0x00007ff71e8cac50 {crt_x64d.exe!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} RLib_x64d.dll!System::Threading::Thread::__threadProcWrapper()
The thread 0x13fc has exited with code 0 (0x0).
destroy 0x0000029d735d6810 {_pxcptacttab=0x00007ff71e8cac50 {crt_x64d.exe!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} Main Thread
FlsFree 7 Main Thread
destroy 0x0000029d735d0680 {_pxcptacttab=0x00007ffcd149a360 {RLib_x64d.dll!const __crt_signal_action_t __acrt_exception_action_table[1]} {...} ...} Main Thread
FlsFree 5 Main Thread
The thread 0x720 has exited with code 0 (0x0).
The program '[680] crt_x64d.exe' has exited with code 0 (0x0).