Consider the following short program:
#include <thread>
int Foo() {
while (1);
}
int main(){
std::thread t(Foo);
std::thread s(Foo);
// (std::thread(Foo));
t.join();
}
This compiles and runs (forever), with
g++ -Wl,--no-as-needed DoubleBufferTest.cc -o DoubleBufferTest -std=c++0x -pthread
In the commented out line, I am trying to use the technique described here to declare a new thread anonymously. However, when that line is commented back in, I can compile but running gives the following error:
terminate called without an active exception
Aborted (core dumped)
How can I correctly declare a thread anonymously?
Note, I am on g++ 4.4.7
.
You can do it like this:
std::thread(Foo).detach();
std::thread
's destructor will call std::terminate
if the thread has not been joined or detached.
So unfortunately you cannot create an anonymous thread object like this - you need a reference to the thread
object in order to call either join()
or detach()
.
Scott Meyers gave a talk at Going Native 2013 where he created an RAII class that wraps a thread and calls join in the destructor. You could do something similar:
class ThreadRAII {
public:
ThreadRAII(std::thread&& thread): t(std::move(thread)) {}
~ThreadRAII() { if (t.joinable()) { t.join(); }
private:
std::thread t;
};
See his blog post or talk for more info.
You could use it like this
(ThreadRAII(std::thread(Foo)));
However, the only reason you'd want to create a thread in this way is if you don't care when (or if) it ends, so in this case, join doesn't make much sense. You should modify the destructor to detach instead:
~ThreadRAII() { if (t.joinable()) { t.detach(); }
As suggested in the comments, you could make it even easier to use by perfect forwarding to an internal thread on construction:
class ThreadRAII2 {
public:
template <typename Func, typename ...Args>
explicit ThreadRAII2(Func&& func, Args&&... args) :
t(func, std::forward<Args>(args)...) { }
~ThreadRAII2() {
if (t.joinable()) t.detach();
}
private:
std::thread t;
};
Then you can use it just like you originally wanted to, no detach necessary:
(ThreadRAII2(Foo));
Or, if Foo
takes arguments (for example Foo(int)
):
(ThreadRAII2(Foo, 42));
I don't think this (the technique you are referring to) is possible with threads.
Take a look here;
30.3.1.3 thread destructor [thread.thread.destr]
~thread();
If joinable() then terminate(), otherwise no effects. [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. — end note ]
Basically the temporary anonymous object (i.e. thread) you are creating is destructed right when execution continues to the next line which violates the above rule.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With