我有一个带有普通构造函数的对象。构造函数有很多初始化工作。这种初始化大部分可以异步执行,因此我正在构造函数中调用新线程。
当线程在堆栈上初始化时,似乎在构造函数退出时该线程被破坏,从而导致崩溃。看起来像这样:
class MyObject
{
MyObject()
{
// Typical initialization
// ...
// Time consuming initialization
std::thread(&MyObject::Init; this); // Create new thread to call Init();
// Crash when exit MyObject() here
}
void Init()
{
// Time consuming operations
}
};
替代方法(有效)是照此在堆上创建线程。
class MyObject
{
std::thread* StartupThread;
MyObject()
{
// Typical initialization
// ...
// Time consuming initialization
StartupThread = new std::thread(&MyObject::Init; this); // Create new thread to call Init();
// Crash when exit MyObject() here
}
~MyObject()
{
StartupThread->join();
delete StartupThread;
}
void Init()
{
// Time consuming operations
}
};
我的问题
使未连接和未处理的线程对象在该对象的生存期内保持生命是否有任何危害,或者我应该尝试在
Init()
完成后立即对其进行清理吗?有没有办法在线程完成时“自动”处置线程,以免线程闲逛?
本质上,我能否以某种方式将线程放在堆栈上而不会像我描述的那样崩溃?
最佳答案
关于什么:
class MyObject
{
MyObject ()
{
f = std::async (std::launch::async, &MyObject::Init, this);
}
private:
void Init ();
std::future<void> f;
};
这使您可以在要同步任务时执行
f.get ()
。如果析构函数是对象的最后一个活动副本,则该析构函数将自动加入(如果您不希望这种行为,则可能要删除该副本构造函数)。请注意,您要在销毁之前的某个时刻进行同步,因为如果
Init
引发异常,则析构函数将进行同步。另外,如果要使用
detach
路线,请参见this。关于c++ - C++ std::thread在堆栈上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28200736/