我正在尝试使用bar
重新构建在thread
类析构函数中销毁shared_ptr成员变量,我认为这可能是堆损坏的原因。我个人觉得在析构函数中使用一个线程很奇怪,所以我想要SO的意见。
指针可能比应用程序更长,因此使用detach
更为可取。如果使用detach
,则不会调用析构函数,但是如果join
可以使用析构函数。
1)以这种方式重置智能指针是错误的吗?
2)为什么在使用std::thread::detach()
时不调用析构函数?
#include <iostream>
#include <thread>
#include <memory>
#include <chrono>
using namespace std;
class foo
{
public:
foo(){longcomputation();}
void longcomputation()
{
std::cout<<" long computation called \n";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
};
class bar
{
public:
bar(): foo_(std::make_shared<foo>()) {}
~bar()
{
std::thread([foo = std::move(foo_)] () mutable
{
foo.reset();
std::cout<<" bar dctor called \n";
}).detach(); // ==========> works with join however
}
private:
std::shared_ptr<foo> foo_;
};
int main()
{
bar bar1;
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "Exiting\n";
}
答案 0 :(得分:0)
这看起来像是处理线程和智能指针的坏方法,虽然我不是一些C ++ Guru,但我认为这是一种用C ++编写整体代码的坏方法(几乎肯定会出现可读性可维护性等问题。 )。
来到析构函数,在可以调度分离的线程之前,析构函数退出,销毁foo_
对象,因此std::move(foo_)
失败。当你使用join()
而不是detach()
时,你正在让析构函数等待线程,这就是它工作的原因。如果我们在分离线程后在析构函数中构建一个sleep也会有效:
~bar()
{
std::thread([foo = std::move(foo_)] () mutable
{
foo.reset();
std::cout<<" bar dctor called \n";
}).detach(); // ==========> works with join however
// this works too
std::this_thread::sleep_for(std::chrono::seconds(1));
}