如何安全地终止线程? (使用指针)c ++

时间:2019-10-19 06:16:17

标签: c++ multithreading c++11

我目前正在使用c ++ 11学习多线程,并且对安全终止线程的方式感到困惑。

在c ++中,我知道创建线程并使用thread.join()安全地确保main()在退出之前等待所有线程完成的方法。

但是,我发现即使不使用thread.join(),某些通过指针实现的多线程代码也能够运行。

class Greating
{
public:

    Greating(const int& _i):i_(_i){}
    ~Greating(){}
    int i_;
    void say()
    {
        std::cout << "Hello World" << i_ << std::endl;
    }

};

int main(){
    Greating greating1(1);
    Greating greating2(2);

    std::thread t1(&Greating::say, greating1);
    std::thread t2(&Greating::say, greating2);
    return 0;
}

上面显示的代码将绝对报告错误“终止,没有活动异常 中止(核心转储)”,因为我没有使用t1.join()和t2.join()。

但是,我发现在某些代码中,当它们使用指针来管理线程时,这不会成为问题,如下所示。

class Greating
{
public:

    Greating(const int& _i):i_(_i){}
    ~Greating(){}
    int i_;
    void say()
    {
        std::cout << "Hello World" << i_ << std::endl;
    }

};

int main(){
    Greating greating1(1);
    Greating greating2(2);

    std::thread* tt1 = new std::thread(&Greating::say, greating1);
    std::thread* tt2 = new std::thread(&Greating::say, greating2);
    return 0;
}

输出为:

Hello WorldHello World12
Hello World12

没有错误报告。这让我很困惑。

所以我的问题是:

  1. 为什么当我们使用指针来管理线程时,不能使用thread.join()函数?
  2. 如何正确终止线程? (可能等待可调用函数完成?)

非常感谢!

1 个答案:

答案 0 :(得分:1)

使用动态分配创建对象时,必须使用operator delete释放内存,以便调用适当的析构函数。

在第一个示例中,创建了两个std::thread对象。在main函数的末尾,调用析构函数std::thread::~thread。由于未连接线程,因此析构函数将报告错误。

另一方面,在第二个示例中,您调用了operator new,因此可以创建具有动态分配的对象。但是,您没有调用operator delete,因此没有调用析构函数。也就是说,程序没有检查线程是否已加入。

因此,正确终止线程的唯一方法是调用std::thread::join。如果要使用指针,则必须执行以下操作:

std::thread *th = new std::thread(foo);
...
th->join();
delete th;