V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xingge
V2EX  ›  程序员

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

  •  
  •   xingge · 2019-11-18 12:34:36 +08:00 · 2467 次点击
    这是一个创建于 1864 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    }

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