Is leaking std::thread undefined behaviour?
Reason why somebody would be interested in
//...
new std::thread (func,arg1,arg2);
}
is that std::thread
destructor(unlike boost::thread
) kills the 开发者_如何学运维thread. func finishes is some time.
My question is this safe in cases:
Case 1: lets say that function takes arg1, arg2 by value.
Case 2: lets say that function takes arg1, arg2 by reference-this sounds bad if you ask me, because I presume that at the end of the scope where thread is created arg1 and arg2 will be cleared by their destructors.BTW is std::thread destructor(that is AFAIK called when func finishes) smart enough to clear all the resources used by thread? I mean if I create 1M threads(ofc not at the same time) with new and all of them finish, have I leaked anything permanently?
An std::thread object represents a thread, it is not a "real" thread, that is a concept managed by the OS.
Therefore, here you're leaking a std::thread object because you don't delete it. The destructor is never called. But the thread it was representing will end when it's instructions will end, like any thread.
If the destructor was called before the end of the instructions, for example if you would have created that object on the stack and there was a lot of things to do in this new thread, then the destructor call would have triggered std::terminate(). You need to call detach() to allow the thread to continue after the std::thread instance is destroyed.
That way, you have to explicitely say if you want or not this thread to end when the std::thread instance is destroyed : if you want it to continue, call detach(); if you want to wait for it to end, call join().
So in your case you leak memory but the thread should continue as the std::thread object lives "forever" because you lost any way to control it.
BTW is std::thread destructor(that is AFAIK called when func finishes) smart enough to clear all the resources used by thread? I mean if I create 1M threads(ofc not at the same time) with new and all of them finish, have I leaked anything permanently?
Normally, the destructor is called automatically when an object on the stack goes out of scope (or during stack unwinding when an exception has been caught). Since the thread object is allocated on the heap using new
the destructor will not be called automatically, some code needs to delete
the object to invoke its destructor. In other words, thread
's destructor is not called when func()
finishes.
This is not OK according to the final text. Specifically, the destructor of a thread that has been neither join
ed nor detach
ed will call std::terminate
.
std::thread
destructor is not called when the callback returns, but when the thread
object goes out of scope, just like any other object. So, a new
'd thread that is never delete
'd will never be destructed, leaking any associated state (and things potentially going horribly wrong if/when the program terminates with any extra threads still running...)
To answer your question about lifetimes, std::thread
is like std::bind
: it stores copies of its arguments and passes those copies to the callback, regardless of whether the callback takes its arguments by value or by reference. You must explicitly wrap arguments with std::ref
to get reference semantics. In this case, as usual, it's up to you to ensure that no dangling references occur (for instance by calling thread::join()
before any referenced variables go out of scope.)
精彩评论