使用堆栈变量pthread内存泄漏

时间:2014-11-27 11:46:16

标签: c++ multithreading memory-leaks pthreads

我注意到当我使用表单

中的线程调用方法时
////main code/////
pthread_t thread;
pthread_create(thread,function,data);
//////////////////

void* function(void* data){

    //work with some data on the heap via a vector on the stack

    std::vector<double> variable (100,1.2345);

    //do contents of thread

    pthread_exit(NULL);
}

尽管没有调用new(除了隐式地在向量变量中),我得到内存泄漏,内存使用量与我以这种方式调用function的次数呈线性关系。 / p>

但是,如果我这样做

void* function(void* data){

    {
    std::vector<double> variable (100,1.2345);

    //do contents of thread
     }

    pthread_exit(NULL);
}

不会发生内存泄漏。

似乎pthread_exit(NULL)没有清除堆栈变量,就像你在使用return的正常函数结束时得到的那样(我说的正确吗?!)所以把它们放在他们的自己的范围确保他们获得自由。

然而,这似乎是一个巨大的kludge。退出pthread时,如何确保正确清除堆栈变量(及其在容器方面的内容)?

3 个答案:

答案 0 :(得分:2)

  

似乎pthread_exit(NULL)没有清除堆栈变量,就像你在返回的正常函数结束时得到的那样(我对此是正确的吗?!)

这就像在非线程代码中调用exit(0)一样,程序立即退出并且不会展开堆栈。 (由于pthreads规范是用C语言定义的,而不是C ++,它没有定义C ++析构函数会发生什么,所以它是特定于平台的。)

  

所以将它们放在自己的范围内可以确保它们被释放。

因为这样,向量的析构函数会在您调用pthread_exit()之前运行。

  

退出pthread时,如何确保正确清除堆栈变量(及其在容器方面的内容)?

只需从线程函数返回,您就不需要使用pthread_exit退出线程启动函数(传递给pthread_create的函数)。 POSIX说:

  

当第一次调用pthread_exit()的线程以外的线程从用于创建它的启动例程返回时,对main()进行隐式调用。

GNU/Linux man page的说法略有不同:

  

从除以外的任何线程的start函数执行返回          主线程导致对pthread_exit()的隐式调用,使用          函数的返回值作为线程的退出状态。

您可以使用pthread_exit从堆栈中的其他函数退出线程,就像您可以使用exit()退出程序而不是从main()返回,但是最外面的函数只是return NULL;(或者你想要的任何返回值)。

使用pthread_exit(x)的唯一时间只是return x;位于main,这会导致程序等待其他线程完成。

答案 1 :(得分:0)

new()的调用隐藏在std::vector<>实施中。

在您的第一个代码示例中,pthread_exit(NULL);将在调用std::vector<>析构函数之前退出该线程,从而导致内存泄漏。

你的第二个例子强制在std::vector<>之前调用pthread_exit(NULL);的析构函数。

答案 2 :(得分:0)

(好吧,我可以看到其他人已经解决了这个问题......是的,这只适用于可连接的线程。如果你试图分离不可连接的线程,你会引发错误。)

您需要在退出时调用pthread_detach(...)配置pthread以进行资源回收。

pthread_detach documentation

这不是为了使任何其他答案无效。但是,如果要在退出时回收堆栈空间,则需要分离任何未加入的可连接子线程!你为什么不想要那个?

即使您通过代码更改解决了这个特定的泄漏,如果您要使用C / C ++中的子线程进行编程,也需要继续使用此知识。 std::threadboost::thread有类似的要求。