winsock和新线程不释放内存

时间:2015-02-15 16:44:02

标签: c++ multithreading winsock2

我有一个非常奇怪的问题。在网上寻找原因并尝试一切。什么都没有帮助。

第一种情况:

(这与预期完全一样.Windows任务管理器显示常量内存大小,但不会增加。)

unsigned long WINAPI thfun(void * arg)
{
    ::Sleep(50);
    ::ExitThread(0);
    return 0;
}


int main(int argc, const wchar_t ** argv)
{
    HANDLE th = 0;
    DWORD thid, err;
    while (true)
    {
        th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
        if (!th)
        {
            err = ::GetLastError();
        }
        ::WaitForSingleObject(th, INFINITE);
    }

    return 0;
}

第二种情况:

unsigned long WINAPI thfun(void * arg)
{
    ::Sleep(50);
    ::ExitThread(0);
    return 0;
}


int main(int argc, const wchar_t ** argv)
{
    WORD ver;
    WSADATA wsadata;
    ver = MAKEWORD(2, 2);
    if (WSAStartup(ver, &wsadata)) return 1;

    ::Sleep(50);

    HANDLE th = 0;
    DWORD thid, err;
    while (true)
    {
        th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
        if (!th)
        {
            err = ::GetLastError();
        }
        ::WaitForSingleObject(th, INFINITE);
    }

    return 0;
}

如果我从winsock调用任何函数,则一旦创建的线程不释放内存。 Windows任务管理器显示了我的应用程序不断增长的内存。

当我使用winsock时,我应该怎样做才能达到与第一种情况相同的行为?

我使用visual studio 2013

非常感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您不要关闭线程句柄。一个常见的错误。

你的核心循环应该是这样的:

while (true)
{
    th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
    if (!th)
    {
        err = ::GetLastError();
    }
    ::WaitForSingleObject(th, INFINITE);
    CloseHandle(th);
}

这两个例子都存在这个问题。第二个样本的记忆增长可能是副作用。

ExitThread(0)从来都不是一个好主意,我不明白为什么微软推荐它为C.因为Winsock API不应该有任何析构函数,它应该不是问题。不过,不要使用它。

<强>更新

我在安装了Antivira个人计算机(我的游戏机)的Windows 7 64位SP1系统上测试了您的代码。也在我的Windows 8 VM(并行)上。两个系统都没有显示您描述的问题并在您的视频中显示。这是恕我直言的好消息,因为它似乎是你的安装问题而不是一般问题。 视频显示每个结束线程只有几个字节的泄漏,每个线程严格线性增长。这就像线程相关信息一样,通常存储在TLS中( T hread L ocal S torage)。此外,它仅在您初始化WSASocket系统时出现。如果WSASocket系统本身就是问题,我们肯定会找到它的报告(但我没有)。我相信一个钩子DLL导致了这个问题,一个DLL通过DllMain通知该进程的任何已启动或结束的线程。任何病毒扫描程序或键盘插件(!)都可能导致这样的问题,因为它们通常使用钩子DLL并操纵管道和套接字等IO。

不幸的是,我只知道一种方法:

  1. 让你的样品释放出来。确保问题存在。
  2. 彻底安装Windows 7
  3. 逐步安装您在Produktive系统上使用的环境。确保在每个步骤后重新启动计算机。
  4. 希望找到罪魁祸首。
  5. 停用或卸载挂钩可能会有所帮助,但不一定需要。不幸的是,在Windows系统上安装程序是最大的反转。

    很抱歉没有轻易回答。