因为一些原因必须要兼容 xp 系统,在 win7 64 位 win10 64 位都没问题
编译环境:vs2019,工具集 v141_xp, crt 版本:14.16.27023, mt release (用 vs2010 的 crt 编译好像没有问题)
代码如下:
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include <tchar.h>
#include <process.h>
unsigned int __stdcall ThreadDemo(LPVOID lpThreadParameter)
{
char str[10000] = { 'a','s','d','f','\0' };
OutputDebugStringA(str);
_endthreadex(0);
return 0;
}
void thread()
{
HANDLE h = (HANDLE)_beginthreadex(NULL, 0, ThreadDemo, NULL, 0, NULL);
if (h)
{
WaitForSingleObject(h, INFINITE);
CloseHandle(h);
} }
int main()
{
while (true)
{
thread();
Sleep(1);
}
return 0;
}
1
tomychen 2019-11-18 14:46:15 +08:00
不要用_endthreadex
至少不要在 线程函数内用这个函数 |
2
xingge OP @tomychen 我试过了,去掉_endthreadex 也是一样的。而且这个函数好像就是在线程内调用的
|
3
iwong0exv2 2019-11-18 18:12:46 +08:00
一直用 std::thread,或者 std::async。
百度_endthreadex,前几条就有答案了。 |
4
tomychen 2019-11-18 18:58:40 +08:00
@xingge
早年写 win32 的时候,隐隐记得_endthread(ex) 和 TerminateThread 要特别小心用 刚刚又跑去 msdn 查了一下 大意为不必要刻意去调用_endthread(ex) 来清理现场,线程函数退出时会自动 call _endthread(ex) 同时提到了这点 Note _endthread and _endthreadex cause C++ destructors pending in the thread not to be called. |
5
xdeng 2019-11-18 19:12:09 +08:00
这里不存在内存泄露吧 句柄泄露?
|
6
xingge OP @iwong0exv2 我就是用 std:thread 内存泄漏后跟踪发现是_beginthreadex 导致的
|
8
xingge OP @tomychen 嗯,谢谢你。但是我去掉了_endthreadex 后,结果还是一样的在 xp 泄漏
|
9
dandycheung 2019-11-18 19:31:45 +08:00 via iPhone
看你的程序风格,显然 Windows API 为主,既然如此为什么不使用 CreateThread 而要用 beginthread 呢?
|
10
dosmlp 2019-11-18 20:01:01 +08:00
好奇为啥非要用 crt 里的函数,这种既不是语言标准又不是操作系统 api 的东西
|
11
ysc3839 2019-11-18 21:12:02 +08:00
@dandycheung @dosmlp
因为微软的文档里写了 https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions. |
14
dosmlp 2019-11-18 21:56:19 +08:00
@ysc3839 你可以试下这个静态 crt 项目 gitee.com/Chuyu-Team/VC-LTL
|
16
dandycheung 2019-11-18 23:27:26 +08:00 via iPhone
@ysc3839 #15 自己遇到了问题,自己有解决掉的责任。当年我处理这类线程问题也是尽量摆脱 crt 带来的负面影响,这跟聪不聪明无关。这不过幸好有人做了一些积累可以造福大家而已,你如果信不过,要么自己搞定,要么去测试一下,干等也不会有什么好办法从天上掉下来。行业里有好多人都自己写过诸如叫做 minicrt 的东西,把必要的部分裁剪出来让自己用,即使微软,也有过不止一套 crt,你又何必胶柱鼓瑟?
|
17
ysc3839 2019-11-19 00:02:18 +08:00
@dandycheung 我没遇到这个问题,不是我需要解决。
我说这个库有种“我比微软聪明”的感觉,是因为它并不是你想象的那样“把必要的部分裁剪出来让自己用”,而是为了减小程序体积,去调用旧版本的运行库,这种做法微软是不推荐的。 “把必要的部分裁剪出来让自己用”,在我看来没有问题,Linux 下都有很多 crt 呢。 |
18
xingge OP 谢谢大家回复,求助小鸭子后得知是 crt 的 bug。这里再说明一下情况
ucrt 的 common_end_thread 函数没有释放 ptd,vista 以上的平台因为有 Fls 回调,所以没有表现出来,xp 必然泄漏,触发条件 exe 工程+ MT。 谢谢初雨团队的 vc-ltl |