mer*_*011 10 c++ multithreading c++11 stdthread
考虑以下简短程序:
#include <thread>
int Foo() {
while (1);
}
int main(){
std::thread t(Foo);
std::thread s(Foo);
// (std::thread(Foo));
t.join();
}
Run Code Online (Sandbox Code Playgroud)
这编译和运行(永远),与
g++ -Wl,--no-as-needed DoubleBufferTest.cc -o DoubleBufferTest -std=c++0x -pthread
Run Code Online (Sandbox Code Playgroud)
在注释掉的行中,我试图使用此处描述的技术匿名声明一个新线程.但是,当该行被注释回来时,我可以编译但运行时会出现以下错误:
terminate called without an active exception
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
我怎样才能正确地匿名声明一个帖子?
请注意,我在g++ 4.4.7.
zmb*_*zmb 12
std::threadstd::terminate如果线程尚未连接或分离,则析构函数将调用.
所以很遗憾你不能像这样创建一个匿名的线程对象 - 你需要引用该thread对象才能调用join()或者detach().
Scott Meyers在2013年的Going Native上发表了一篇演讲,他创建了一个包含线程的RAII类,并在析构函数中调用join.你可以做类似的事情:
class ThreadRAII {
public:
ThreadRAII(std::thread&& thread): t(std::move(thread)) {}
~ThreadRAII() { if (t.joinable()) { t.join(); }
private:
std::thread t;
};
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它
(ThreadRAII(std::thread(Foo)));
Run Code Online (Sandbox Code Playgroud)
但是,您希望以这种方式创建线程的唯一原因是,如果您不关心它何时(或如果)结束,那么在这种情况下,连接没有多大意义.您应该修改析构函数以分离:
~ThreadRAII() { if (t.joinable()) { t.detach(); }
Run Code Online (Sandbox Code Playgroud)
正如评论中所建议的那样,通过完美转发到构造中的内部线程,您可以更容易地使用它:
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;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像你原来想的那样使用它,不需要分离:
(ThreadRAII2(Foo));
Run Code Online (Sandbox Code Playgroud)
或者,如果Foo接受参数(例如Foo(int)):
(ThreadRAII2(Foo, 42));
Run Code Online (Sandbox Code Playgroud)