_beginthreadex 在 windows xp sp3 系统内存泄漏怎么办

2019-11-18 12:34:36 +08:00
 xingge

因为一些原因必须要兼容 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;

}

2462 次点击
所在节点    程序员
18 条回复
tomychen
2019-11-18 14:46:15 +08:00
不要用_endthreadex
至少不要在 线程函数内用这个函数
xingge
2019-11-18 17:32:34 +08:00
@tomychen 我试过了,去掉_endthreadex 也是一样的。而且这个函数好像就是在线程内调用的
iwong0exv2
2019-11-18 18:12:46 +08:00
一直用 std::thread,或者 std::async。
百度_endthreadex,前几条就有答案了。
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.
xdeng
2019-11-18 19:12:09 +08:00
这里不存在内存泄露吧 句柄泄露?
xingge
2019-11-18 19:12:51 +08:00
@iwong0exv2 我就是用 std:thread 内存泄漏后跟踪发现是_beginthreadex 导致的
xingge
2019-11-18 19:13:54 +08:00
@xdeng xp 系统存在,其它系统没事
xingge
2019-11-18 19:18:58 +08:00
@tomychen 嗯,谢谢你。但是我去掉了_endthreadex 后,结果还是一样的在 xp 泄漏
dandycheung
2019-11-18 19:31:45 +08:00
看你的程序风格,显然 Windows API 为主,既然如此为什么不使用 CreateThread 而要用 beginthread 呢?
dosmlp
2019-11-18 20:01:01 +08:00
好奇为啥非要用 crt 里的函数,这种既不是语言标准又不是操作系统 api 的东西
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.
dosmlp
2019-11-18 21:45:15 +08:00
@ysc3839 不要用 crt 里的函数不就行了
ysc3839
2019-11-18 21:47:53 +08:00
@dosmlp 这里当然说的是要用的情况。
dosmlp
2019-11-18 21:56:19 +08:00
@ysc3839 你可以试下这个静态 crt 项目 gitee.com/Chuyu-Team/VC-LTL
ysc3839
2019-11-18 22:30:48 +08:00
@dosmlp 这个项目我之前就听说过了,但是我觉得更不靠谱。有种“我比微软聪明”的感觉。
dandycheung
2019-11-18 23:27:26 +08:00
@ysc3839 #15 自己遇到了问题,自己有解决掉的责任。当年我处理这类线程问题也是尽量摆脱 crt 带来的负面影响,这跟聪不聪明无关。这不过幸好有人做了一些积累可以造福大家而已,你如果信不过,要么自己搞定,要么去测试一下,干等也不会有什么好办法从天上掉下来。行业里有好多人都自己写过诸如叫做 minicrt 的东西,把必要的部分裁剪出来让自己用,即使微软,也有过不止一套 crt,你又何必胶柱鼓瑟?
ysc3839
2019-11-19 00:02:18 +08:00
@dandycheung 我没遇到这个问题,不是我需要解决。
我说这个库有种“我比微软聪明”的感觉,是因为它并不是你想象的那样“把必要的部分裁剪出来让自己用”,而是为了减小程序体积,去调用旧版本的运行库,这种做法微软是不推荐的。
“把必要的部分裁剪出来让自己用”,在我看来没有问题,Linux 下都有很多 crt 呢。
xingge
2019-11-19 14:00:17 +08:00
谢谢大家回复,求助小鸭子后得知是 crt 的 bug。这里再说明一下情况
ucrt 的 common_end_thread 函数没有释放 ptd,vista 以上的平台因为有 Fls 回调,所以没有表现出来,xp 必然泄漏,触发条件 exe 工程+ MT。
谢谢初雨团队的 vc-ltl

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/620613

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX