pthread memory leak with stack variables

2019-05-30 18:10发布

I have noticed that when I call a method using a thread in the form

////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);
}

despite having no calls to new (except implicitly in vector variable) I get a memory leak with the amount of memory usage going linearly with the number of times I call function in this way.

However if I do this

void* function(void* data){

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

    //do contents of thread
     }

    pthread_exit(NULL);
}

the memory leak doesn't occur.

It seems that pthread_exit(NULL)doesn't clear the stack variables like you would get at the end of a normal function with return (I am correct about that right?!) so putting them within their own scope ensures they get freed.

However, this seems like a massive kludge. How do I ensure the stack variables (and their contents on the heap in terms of containers) are cleared properly when exiting a pthread?

3条回答
冷血范
2楼-- · 2019-05-30 18:35

The calls to new() are hidden in the std::vector<> implementation.

In your first code sample pthread_exit(NULL); will exit the thread, before the std::vector<> destructor is called, thus the memory leaks.

Your second example forces the destructor of the std::vector<> is called before pthread_exit(NULL);.

查看更多
别忘想泡老子
3楼-- · 2019-05-30 18:40

It seems that pthread_exit(NULL) doesn't clear the stack variables like you would get at the end of a normal function with return (I am correct about that right?!)

That's like calling exit(0) in non-threaded code, the program exits right away and doesn't unwind the stack. (Since the pthreads spec is defined in terms of C, not C++, it doesn't define what happens with C++ destructors, so it's platform specific).

so putting them within their own scope ensures they get freed.

Because that way the vector's destructor runs before you call pthread_exit().

How do I ensure the stack variables (and their contents on the heap in terms of containers) are cleared properly when exiting a pthread?

Just return from the thread function, you don't need to use pthread_exit to exit from the thread start function (the one that was passed to pthread_create). POSIX says:

An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it.

and the GNU/Linux man page says the same thing slightly differently:

Performing a return from the start function of any thread other than the main thread results in an implicit call to pthread_exit(), using the function's return value as the thread's exit status.

You can use pthread_exit to exit the thread from other functions further down the stack, just like you can use exit() to quit a program instead of returning from main(), but at the outermost function just return NULL; (or whatever return value you want).

The only time using pthread_exit(x) makes a difference to simply return x; is in main where it will cause the program to wait until other threads finish.

查看更多
戒情不戒烟
4楼-- · 2019-05-30 18:47

(Okay, I can see that someone else addressed this issue already... And yes, this only applies to joinable threads. If you try to detach a non-joinable thread you raise an error.)

You'll need to call pthread_detach(...) to configure the pthread for resource reclamation on exit.

pthread_detach documentation

This is not to invalidate any of the other answers. However, you'll need to detach any joinable child thread that you don't join, if you want its stack space to be reclaimed when it exits! Why would you ever not want that?

Even if you solve this particular leak with a code change, you'll need to move forward with this awareness if you are going to program with child threads in C/C++. std::thread and boost::thread have similar requirements.

查看更多
登录 后发表回答