[英]Destructor called before end of scope
The following program chrashes. 以下程序崩溃。 But I don't really understand why.
但是我真的不明白为什么。 The boolean my_shared_resouce is in real life an asynchonous queue that eventually stops the loop inside of the thread via message passing.
布尔值my_shared_resouce实际上是一个异步队列,该队列最终通过消息传递停止线程内部的循环。 However, the following program crashes because the destructor seems to be called multiple times.
但是,以下程序崩溃,因为似乎多次调用了析构函数。 And the first time it does is long before the sleep in the main() finishes.
而且第一次是在main()的睡眠完成之前很长时间。 If i remove the
delete my_shared_resource;
如果我删除
delete my_shared_resource;
I can see the destructor is called three times... However, following my current understanding the destructor should only be called when main()
finishes. 我可以看到析构函数被调用了三次……但是,按照我目前的理解,析构函数应该仅在
main()
完成时才调用。
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
class ThreadedClass {
public:
ThreadedClass() {
my_shared_resource = new bool(true);
}
virtual ~ThreadedClass() {
delete my_shared_resource;
cout << "destructor" << endl;
}
void operator()(){
loop();
}
void stop() {
*my_shared_resource = false;
}
private:
void loop() {
while (*my_shared_resource) {
// do some work
this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
bool* my_shared_resource;
};
int main(int argc, char** argv) {
ThreadedClass instance;
std::thread t(instance);
this_thread::sleep_for(std::chrono::milliseconds(1000));
cout << "Did some work in main thread." << endl;
instance.stop();
t.join();
return 0;
}
compiled with g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 用g ++编译(Ubuntu 4.8.4-2ubuntu1〜14.04)4.8.4
compiled as g++ --std=c++0x thread.cpp -pthread 编译为g ++ --std = c ++ 0x thread.cpp -pthread
Would someone please enlighten me what is wrong about this design. 有人能启发我这个设计的问题是什么。
When ThreadedClass
gets copied both copies point to the same my_shared_resource
, and both will delete it. 复制
ThreadedClass
时,两个副本都指向相同的my_shared_resource
,并且两者都将删除它。
Use a std::shared_ptr<bool>
instead: 请使用
std::shared_ptr<bool>
代替:
class ThreadedClass {
public:
ThreadedClass() : shared_resource(new bool(true)) { }
virtual ~ThreadedClass() { }
void operator()() { loop(); }
void stop() { *shared_resource = false; }
private:
void loop() {
while (*shared_resource) {
// Do some work.
this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
std::shared_ptr<bool> shared_resource;
};
According to http://en.cppreference.com/w/cpp/thread/thread/thread you are calling: 根据http://en.cppreference.com/w/cpp/thread/thread/thread,您正在调用:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
which 哪一个
Creates new std::thread object and associates it with a thread of execution. 创建新的std :: thread对象,并将其与执行线程相关联。 First the constructor copies/moves all arguments (both the function object f and all args...) to thread-accessible storage
首先,构造函数将所有参数(函数对象f和所有args ...)复制/移动到线程可访问的存储中
Thus your my_shared_resourse
pointer gets copied and shared between several copies of the thread object and gets destroyed in several places. 因此,您的
my_shared_resourse
指针将在线程对象的多个副本之间复制和共享,并在多个位置被破坏。 Either define the appropriate copy constructor/assignment operator or use shared pointers. 定义适当的复制构造函数/赋值运算符或使用共享指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.