[英]Destroying a shared_ptr member variable in the class destructor using a thread
I am trying to recreate destroying a shared_ptr member variable in the bar
class destructor using a thread
which I feel may be the reason for a heap corruption. 我正在尝试使用一个thread
创建重新破坏销毁bar
类析构函数中的shared_ptr成员变量,我认为这可能是堆损坏的原因。 I personally feel it is strange to use a thread in a destructor, so I want the opinion from SO. 我个人觉得在析构函数中使用线程很奇怪,所以我希望得到SO的意见。
The pointer may outlive the application , so using detach
is more desirable. 指针可能会超出应用程序的寿命,因此使用detach
更可取。 The destructor is not called if detach
used, however it works if join
. 如果使用detach
,则不会调用析构函数,但是如果join
,则可以使用。
1) Is it wrong to reset a smart pointer this way? 1)这样重置智能指针是否错误?
2) Why the destructor is not called when std::thread::detach()
was used ? 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";
}
This does look like a bad way to handle threads and smart pointers and though I am not some C++ Guru, I would say this is a bad way to code in C++ overall (there will almost surely be issues of readability maintainability etc.). 这看起来确实是处理线程和智能指针的一种不好的方式,尽管我不是C ++专家,但我会说这是在C ++总体上进行编码的一种不好的方式(几乎肯定会存在可读性,可维护性等问题)。
Coming to the destructor, before the detached thread could be scheduled, the destructor exits, destroying the foo_
object and hence, std::move(foo_)
fails. 进入析构函数之前,在可以调度分离线程之前,析构函数将退出,破坏foo_
对象,因此std::move(foo_)
失败。 And when you use join()
instead of detach()
, you are making the destructor wait for the thread, which is why it works. 当使用join()
而不是detach()
,您使析构函数等待线程,这就是它起作用的原因。 It would also work if we build a sleep in the destructor after detaching the thread: 如果在分离线程后在析构函数中建立睡眠,这也将起作用:
~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));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.