I have an object that uses pthreads. Its constructor creates several threads.
The class's destructor calls pthread_join on all these threads.
What would happen during a delete, if it didn't? I.e., what happens to a non-terminated thread, if the delete operator suddenly tries to deallocate the object?
Thanks in advance for all replies. :)
With the join, your destructor will block until all of the joined threads have exited.
pthread_join
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then
pthread_join() returns immediately. The thread specified by thread
must be joinable.
If you don't join with the threads, they will continue to run. This can have various consequences depending on if you invoke undefined behavior (eg, try to reference the deleted object after the destructor exits from one of the still running threads).
Deleting the pthread_t objects could have consequences depending on your system (I don't know every implementation of pthreads), but in general they're only references to the underlying system object representing the thread. So you will lose your reference to that thread, and potentially be unable to join with it later, but the thread would continue to run.
Related
I don't understand why when an std::thread is destructed it must be in join() or detach() state.
Join waits for the thread to finish, and detach doesn't.
It seems that there is some middle state which I'm not understanding.
Because my understanding is that join and detach are complementary: if I don't call join() than detach() is the default.
Put it this way, let's say you're writing a program that creates a thread and only later in the life of this thread you call join(), so up until you call join the thread was basically running as if it was detached, no?
Logically detach() should be the default behavior for threads because that is the definition of what threads are, they are parallelly executed irrespective of other threads.
So when the thread object gets destructed why is terminate() called? Why can't the standard simply treat the thread as being detached?
I'm not understanding the rationale behind terminating a program when either join() or detached() wasn't called before the thread was destructed. What is the purpose of this?
UPDATE:
I recently came across this. Anthony Williams states in his book, Concurrency In Action, "One of the proposals for C++17 was for a joining_thread class that would be similar to std::thread, except that it would automatically join in the destructor much like scoped_thread does. This didn’t get consensus in the committee, so it wasn’t accepted into the standard (though it’s still on track for C++20 as std::jthread)..."
Technically the answer is "because the spec says so" but that is an obtuse answer. We can't read the designers' minds, but here are some issues that may have contributed:
With POSIX pthreads, child threads must be joined after they have exited, or else they continue to occupy system resources (like a process table entry in the kernel). This is done via pthread_join().
Windows has a somewhat analogous issue if the process holds a HANDLE to the child thread; although Windows doesn't require a full join, the process must still call CloseHandle() to release its refcount on the thread.
Since std::thread is a cross-platform abstraction, it's constrained by the POSIX requirement which requires the join.
In theory the std::thread destructor could have called pthread_join() instead of throwing an exception, but that (subjectively) that may increase the risk of deadlock. Whereas a properly written program would know when to insert the join at a safe time.
See also:
https://en.wikipedia.org/wiki/Zombie_process
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
https://learn.microsoft.com/en-us/windows/win32/procthread/terminating-a-process
You're getting confused because you're conflating the std::thread object with the thread of execution it refers to. A std::thread object is a C++ object (a bunch of bytes in memory) that acts as a reference to a thread of execution. When you call std::thread::detach what happens is that the std::thread object is "detached" from the thread of execution -- it no longer refers to (any) thread of execution, and the thread of execution continues running independently. But the std::thread object still exists, until it is destroyed.
When a thread of execution completes, it stores its exit info into the std::thread object that refers to it, if there is one (If it was detached, then there isn't one, so the exit info is just thrown away.) It has no other effect on the std::thread object -- in particular the std::thread object is not destroyed and continues to exist until someone else destroys it.
You might want a thread to completely clean up after itself when it's done leaving no traces. This would mean that you could start a thread and then forget about it.
But you might also want to be able to manage a thread while it was running and get any return value it had provided when it was done. In this case, if a thread cleaned up after itself when it was done, your attempt to manage it could cause a crash because you would be accessing a handle that might be invalid. And to check for the return value when the thread finishes, the return value has to be stored somewhere, which means the thread can't be fully cleaned up because the place where the return value is stored has to be left around.
In most frameworks, by default, you get the second option. You can manage the thread (by interrupting it, sending signals to it, joining it, or whatever) but it can't clean up after itself. If you prefer the first option, there's a function to get that behavior (detach) but that means that you may not be able to access the thread because it may or may not continue to exist.
When a thread handle for an active thread goes out of scope you have a couple of options:
join
detach
kill thread
kill program
Each one of these options is terrible. No matter which one you pick it will be surprising, confusing and not what you wanted in most situations.
Arguably the joining thread you mentioned already exists in the form of std::async which gives you a std::future that blocks until the created thread is done, so doing an implicit join. But the many questions about why
std::async(std::launch::async, f);
g();
does not run f and g concurrently indicate how confusing that is. The best approach I'm aware of is to define it to be a programming error and have the programmer fix it, so an assert would be most appropriate. Unfortunately the standard went with std::terminate instead.
If you really want a detaching thread just write a little wrapper around std::thread that does if (thread.joinable()) thread.detach(); in its destructor or whichever handler you want.
Question: "So when the thread object gets destructed why is terminate() called? Why can't the standard simply treat the thread as being detached?"
Answer: Yes, I agree that it terminates the program badly but such design has its reasons. Without the std::terminate() mechanism in the destructor std::thread::~thread, if the users really wanted to do join(), but for some reason "join" didn't execute (for e.g. exception was thrown) then the new_thread will run in the background just like the detach() behaviors. This might cause undefined behaviors because that was not the original intention of the user to have a detached thread.
So I have a strange situation here. I have the following code:
int main()
{
std::shared_ptr<MyClassA> classA = std::shared_ptr<MyClassA>(new MyClassA);
std::shared_ptr<MyClassB> classB = std::shared_ptr<MyClassB>(new MyClassB(classA));
boost::thread_group threadGroup;
// This thread is essentially an infinite loop waiting for data on a socket
threadGroup.create_thread( boost::bind(&MyClassB::method1, classB) );
...do stuff
return 0;
}
MyClassB opens several resources, that are not deallocated when the program exits. However, if I remove the call to create_thread, the resources are deallocated. I put a printout in the destructor of MyClassB, and verified that it's not being called if that thread is created.
Anybody have any insight into what's going on here?
According to documentation boost::thread_group destructor destroys all onwed thread. boost::thread destructor in order:
if defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If *this has an associated thread of execution, calls detach(), DEPRECATED
BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to std::terminate. Destroys *this.
So you need to join threads explicitly. You can do that by calling boost::thread_group::join_all() at the end of your program.
Since you are passing shared pointer to class B to your thread, your thread now shares the instance. Until this threads exits NATURALLY, this resource will not be freed.
// This thread is essentially an infinite loop waiting for data on a socket
This comment is very telling. Your thread may run forever, well past the end of the program. If that's the case, you need to detach the thread before you exit main, and you should expect not to see the destructor called. The thread is still alive and shares ownership of that object.
...do stuff
If that ...do stuff doesn't involve either detaching or joining that thread, you are invoking undefined behavior in Boost. That undefined behavior becomes very well defined if you switch from using boost::thread to using std::thread.
That well-defined behavior is something that no sane programmer wants to invoke: Destructing a joinable thread results in a call to std::terminate(). The behavior of std::terminate is implementation-dependent, but typically it means "stop right now". Destructors aren't called, exit handlers aren't called.
You need to either join or detach that thread.
I would like to have boost thread object being deleted together with exiting from thread entry function. Is it something wrong if I start the thread function and pass a shared pointer to object, which owns thread object instance and then, when thread function exits, it destroys the this object together with thread object at the same time?
EDIT:
Maybe I will describe why I want to do that. I have to use low level dbus API. What I want to do is to create the adapter class, which will start its own thread and wait for incoming messages until the DISCONNECT message arrives. If it arrives I want to close the thread and kill the Adapter itself. The adapter is an Active Object, which runs the method sent to its scheduler. These methods put themselves on the scheduler queue once again after reading message from dbus. But if it is DISCONNECT message, they should not sent the method but just exit scheduler thread, destroying the Adapter object. hmmm looks like it is too complicated...
From the Boost.Thread documentation you can see that a thread object that is joinable should not be deleted, otherwise std::terminate will be called.
So you should assure that if the thread is joinable, either join() or detach() should be called in the destructor of the object owning the thread. Note: if the thread itself is destroying the object, join() is not an option. The thread would attempt to join itself, resulting in a deadlock.
However, if you keep these restrictions in mind, you can destroy a thread from within its own thread of execution.
You can do this, but you probably should not.
The main purpose of the boost::thread object is that you can monitor the associated thread. Having a thread monitor itself does not make much sense in most scenarios.
As was suggested by the other answers, you could just detach the thread and throw the boost::thread object away. Doing this is usually considered bad style, unless the monitoring responsibility has been transferred to another object first. For example, many simple worker threads set a future upon completion. The future already provides all the monitoring we need, so we can detach the thread.
You should never detach a thread completely such that you lose all means of monitoring it. You must at least be able to guarantee a clean shutdown, which becomes impossible for all but the most trivial threads if you detach them completely.
I am not sure if that addresses your use case but it sounds to me like you don't have to do this.
The lifetime of the boost::thread object does not necessarily coincide with the thread itself. Meaning that if you don't care you can just as well start the thread, call detach() on it and have the object run out of scope. Then it is deleted but the thread will still run until it's function is finished. The only thing is, you won't be able to join it. So if your program finishes while the thread still runs it will crash.
In case you do care about this stuff, the question might be wrong because in this case you would store the objects and call join() on them before deleting.
If I am right, the std::async uses a new thread and calls the method in it. I was wondering what happens if the main thread or the parent thread dies. Does the thread controlling the async method dies as well.
There is no concept of a "parent" thread in C++, each thread is independent of the one that it was created by. However, the main thread is special and if it returns from main() or calls exit() then the entire application is terminated even if other threads are still running. Once that happens, the program has undefined behaviour if the still-running threads access any global variables or automatic objects that were on the main thread's stack, or use any standard library objects or call any function not permitted in signal handlers.
In short, do not let other threads run after main completes if you expect sensible results.
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.
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.
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.
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.
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.