在函数方法中使用std :: thread

Ste*_*ano 0 c++ multithreading c++11

这段代码按预期工作(它打印"procedure()")

#include <iostream>
#include <thread>

class myClass{
public:
    myClass(){};
    ~myClass(){};
    void run(){std::cout << "run()"<<std::endl;};
    void procedure(){std::cout << "procedure()"<<std::endl;};
};


int main(int argc, char *argv[]){
    myClass* c = new myClass();
    std::thread c_thread(&myClass::procedure,c);
    c_thread.join();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在我不喜欢调用者必须知道我的类启动一个线程的事实!所以我会优先在run方法的构造函数中隐藏启动线程.所以我写了下面的代码:

#include <iostream>
#include <thread>
class myClass{
public:
    myClass(){};
    ~myClass(){};
    void run(){
        std::cout << "run()"<<std::endl;
        std::thread c_thread(&myClass::procedure,this);     
    };
    void procedure(){std::cout << "procedure()"<<std::endl;};
};


int main(int argc, char *argv[]){
    myClass* c = new myClass();

    c->run();
    while(true){}

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这最终会出现以下错误:

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
run()
[New Thread 0x7ffff6fdd700 (LWP 4485)]
terminate called without an active exception

Program received signal SIGABRT, Aborted.
0x00007ffff70135f7 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.1.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc++-4.8.5-4.el7.x86_64
(gdb) bt
#0  0x00007ffff70135f7 in raise () from /lib64/libc.so.6
#1  0x00007ffff7014ce8 in abort () from /lib64/libc.so.6
#2  0x00007ffff79179d5 in __gnu_cxx::__verbose_terminate_handler() () from /lib64/libstdc++.so.6
#3  0x00007ffff7915946 in ?? () from /lib64/libstdc++.so.6
#4  0x00007ffff7915973 in std::terminate() () from /lib64/libstdc++.so.6
#5  0x000000000040109d in std::thread::~thread (this=0x7fffffffdeb0, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/thread:143
#6  0x00000000004011e1 in myClass::run (this=0x606010) at test2.cpp:9
#7  0x0000000000400f65 in main (argc=1, argv=0x7fffffffe008) at test2.cpp:17
(gdb) q
Run Code Online (Sandbox Code Playgroud)

谁知道原因?

Nat*_*ica 5

当你调用c->run();它执行

void run(){
    std::cout << "run()"<<std::endl;
    std::thread c_thread(&myClass::procedure,this);     
};
Run Code Online (Sandbox Code Playgroud)

当函数结束时c_thread被破坏.因为你从未调用过它join()或者detach()c_thread仍然可以连接,这会导致析构函数抛出异常.看到std::thread::~thread()

你需要在析构函数中创建c_thread一个成员,你需要调用它或者在它上面.这将允许销毁线程对象而不抛出异常.如果你调用析构函数将不会结束直到结束.如果你调用那么析构函数将立即完成但线程将继续运行直到函数结束.myClassmyClassjoin()detach()join()myClass::proceduredetach()