views:

441

answers:

4

I am working on a multithreaded program using C++ and Boost. I am using a helper thread to eagerly initialize a resource asynchronously. If I detach the thread and all references to the thread go out of scope, have I leaked any resources? Or does the thread clean-up after itself (i.e. it's stack and any other system resources needed for the itself)?

From what I can see in the docs (and what I recall from pthreads 8 years ago), there's not explicit "destory thread" call that needs to be made.

I would like the thread to execute asynchronously and when it comes time to use the resource, I will check if an error has occured. The rough bit of code would look something like:

//Assume this won't get called frequently enough that next_resource won't get promoted
//before the thread finishes.
PromoteResource() {
   current_resource_ptr = next_resource_ptr;
   next_resource_ptr.reset(new Resource());
   callable = bind(Resource::Initialize, next_resource); //not correct syntax, but I hope it's clear
   boost::thread t(callable);
   t.start();
}

Of course--I understand that normal memory-handling problems still exist (forget to delete, bad exception handling, etc)... I just need confirmation that the thread itself isn't a "leak".

Edit: A point of clarification, I want to make sure this isn't technically a leak:

void Run() {
   sleep(10 seconds);
}

void DoSomething(...) {
   thread t(Run);
   t.run();
} //thread detaches, will clean itself up--the thread itself isn't a 'leak'?

I'm fairly certain everything is cleaned up after 10 seconds-ish, but I want to be absolutely certain.

+1  A: 

If I'm not mistaken, on Windows Xp all resources used by a process will be released when the process terminates, but that isn't true for threads.

Nick D
+1  A: 

Yes, the resources are automatically released upon thread termination. This is a perfectly normal and acceptable thing to do to have a background thread.

To clean up after a thread you must either join it, or detach it (in which case you can no longer join it).

Here's a quote from the boost thread docs that somewhat explains that (but not exactly).

When the boost::thread object that represents a thread of execution is destroyed the thread becomes detached. Once a thread is detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed, or the program is terminated. A thread can also be detached by explicitly invoking the detach() member function on the boost::thread object. In this case, the boost::thread object ceases to represent the now-detached thread, and instead represents Not-a-Thread.

In order to wait for a thread of execution to finish, the join() or timed_join() member functions of the boost::thread object must be used. join() will block the calling thread until the thread represented by the boost::thread object has completed. If the thread of execution represented by the boost::thread object has already completed, or the boost::thread object represents Not-a-Thread, then join() returns immediately. timed_join() is similar, except that a call to timed_join() will also return if the thread being waited for does not complete when the specified time has elapsed.

Greg Rogers
+2  A: 

The thread's stack gets cleaned up when it exits, but not anything else. This means that anything it allocated on the heap or anywhere else (in pre-existing data structures, for example) will get left when it quits.

Additionally any OS-level objects (file handle, socket etc) will be left lying around (unless you're using a wrapper object which closes them in its destructor).

But programs which frequently create / destroy threads should probably mostly free everything that they allocate in the same thread as it's the only way of keeping the programmer sane.

MarkR
Mark: Sounds like the standard memory management rules apply. The only "resources" that is specific to the thread itself is its stack and you are saying that the thread's stack is cleaned up. As far as the other resources, I'm using RIAA techniques (or equivalent wrappers) to avoid leaks.
James Schek
If you're using RIAA objects, then anything which is completely "owned" by that thread should get thrown out automatically when its stack is cleared at the end of the main function just before the thread quits. The only things to watch for are circular references, and things which aren't fully "owned" such as things which have strong shared references elsewhere in your application.
MarkR
+1  A: 

In Win32, as soon as the thread's main function, called ThreadProc in the documentation, finishes, the thread is cleaned up. Any resources allocated by you inside the ThreadProc you'll need to clean up explicitly, of course.

Thomas