我有一个主线程,我在其中创建了一些独立的类实例。
实例本身包含大量数据,需要经常删除和重新创建。实际删除它们需要一段时间(包含大量数据的 100k 个实例 == 删除时间长),所以我的想法是将它们的删除卸载到一个单独的线程,从而允许 UI 在它们被删除时保持响应被删除并清理内存。
这是一些伪代码,显示了我要删除的类:
class myObj
{
std::vector<int> bigData; //eventually filled with lots of data
};
这里有一些伪代码来展示默认的阻塞删除方法是如何工作的:
void deleteStuff (std::vector<myObj*> *objects) //this works fine
{
for (auto obj : *objects)
{
delete obj;
}
objects->clear();
}
但是当我以这种方式删除东西时,我的程序崩溃了。为什么?
void deleteStuffThreaded(std::vector<myObj*> *objects)
{
for (auto obj : *objects)
{
delete obj;
}
objects->clear();
}
void deleteStuff(std::vector<myObj*> *objects) //this crashes
{
std::thread deleteThread(&deleteStuffThreaded, objects);
}
值得注意的是,一旦 deleteStuff 返回,“objects” vector 就再也不会被触及,因此这不是在线程中清除“objects”与在其他地方访问它之间的代码中其他地方发生的竞争条件。有时,当我逐步执行代码时,“deleteStuffThreaded”函数在到达“清除”行之前崩溃。
Google 告诉我理论上可以在与创建它们的线程不同的线程中删除对象,而且我知道崩溃不是由于在“deleteStuff”返回后尝试访问已删除对象之一的属性造成的,因为单线程版本工作正常(我检查了我的代码,那些实例再也没有被触及)。
最佳答案
std::thread
析构函数文档说:
~thread(); (since C++11)
Destroys the thread object.
If *this has an associated thread (joinable() == true), std::terminate() is called.
因此,由于您尚未加入或分离线程,程序将在您的deleteStuff
函数结束并且线程对象的析构函数被调用时终止
由于您可能想要触发并忘记您的线程,请执行以下操作:
std::thread deleteThread(&deleteStuffThreaded, objects);
deleteThread.detach();
关于c++ - 删除不同线程中的对象会导致崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53054722/