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?
The calls to
new()
are hidden in thestd::vector<>
implementation.In your first code sample
pthread_exit(NULL);
will exit the thread, before thestd::vector<>
destructor is called, thus the memory leaks.Your second example forces the destructor of the
std::vector<>
is called beforepthread_exit(NULL);
.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).Because that way the vector's destructor runs before you call
pthread_exit()
.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 topthread_create
). POSIX says:and the GNU/Linux man page says the same thing slightly differently:
You can use
pthread_exit
to exit the thread from other functions further down the stack, just like you can useexit()
to quit a program instead of returning frommain()
, but at the outermost function justreturn NULL;
(or whatever return value you want).The only time using
pthread_exit(x)
makes a difference to simplyreturn x;
is inmain
where it will cause the program to wait until other threads finish.(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
andboost::thread
have similar requirements.