V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xingge
V2EX  ›  程序员

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

  •  
  •   xingge · Nov 18, 2019 · 3208 views
    This topic created in 2359 days ago, the information mentioned may be changed or developed.

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