C ++创建具有非静态成员函数的线程

Posted

技术标签:

【中文标题】C ++创建具有非静态成员函数的线程【英文标题】:C++ Creating a thread with non static member function 【发布时间】:2020-04-15 02:11:45 【问题描述】:

我正在尝试使用类的非静态成员函数在 C++ 中创建一个新线程。然而,这似乎在 Mac 上一直崩溃,我不知道为什么。这是一个最小的例子:

class A 
public:
    void hello() 
        cout << "hello" << endl;
    

    A() 
        cout << "As constructor" << endl;
        // thread(&hello, this);
    

    void start() 
        thread(&A::hello, this);
    
;

int main()
    A test;
    test.start();


我正在用这个在 mac 上编译:

clang++ -std=c++11 -stdlib=libc++ -pthread -o hello thread.cpp 

我错过了什么?

【问题讨论】:

您使用哪本 C++ 教科书来学习如何在 C++ 程序中正确使用线程?你的教科书应该解释加入执行线程的正确过程,以避免这种崩溃。 【参考方案1】:

您应该调用std::thread::join 来阻塞当前线程,直到线程创建完成执行。否则当前线程可能会结束并导致对象test被提前销毁。

例如

void start() 
    thread t(&A::hello, this);
    t.join();

【讨论】:

请注意,像这样在start() 内部使用本地thread 对象和join() 可以有效地使start() 同步,完全违背了使用线程的目的。该解决方案与void start() hello(); 的效果基本相同,只是操作系统开销更大。【参考方案2】:

问题有两个方面:

main() 在销毁 test 对象之前不会等待线程完成,这会导致崩溃。

start() 没有在任何地方存储std::thread 对象,因此它会立即被销毁,这将导致崩溃,因为线程仍然可以连接并且std::thread 析构函数调用std::terminate() 来终止调用如果线程可连接,则处理。

试试类似的方法:

class A 
private:
    std::thread thrd;

public:
    void hello() 
        cout << "hello" << endl;
    

    A() 
        cout << "As constructor" << endl;
    

    ~A() 
        cout << "As destructor" << endl;
        wait();
    

    void start() 
        thrd = thread(&A::hello, this);
    

    void wait() 
        if (thrd.joinable())
            thrd.join();
    
;

int main()
    A test;
    test.start();
    // do something else while the thread is running...

【讨论】:

以上是关于C ++创建具有非静态成员函数的线程的主要内容,如果未能解决你的问题,请参考以下文章

MFC中多线程中静态函数调用成员函数的问题

C ++创建指向标头内所有公共静态成员函数的指针数组,然后使用它

c++11的std::thread能用类的成员函数构造一个线程吗?语法怎样?

具有类名的数据成员

c++ std::thread 与静态成员挂起

指向具有私有构造函数的类的类成员的指针