我一直在执行async函数。目前,该函数是同步调用的。它在列表中存储一些信息,并在以后提供有关列表项的信息。
// Read Infos
void MyManager::Read(HWND parent)
{
// do some work...
mItemInfos.push_back(info);
}
// provide information
ItemInfo* MyManager::GetInfo(int index)
{
return mItemInfos.at(index);
}
现在我想做异步读取。我定义了一种新方法
void MyManager::BeginRead(HWND parent)
{
mFuture = std::async(std::launch::async, &MyManager::Read, this, parent);
}
现在,当Read
方法中抛出异常时,我永远不会知道,因为mFuture.get()
方法从未被调用。要解决此问题,我应该只在GetInfo()
中调用mFuture.get()
吗?每次我打GetInfo()
?
我的整个方法似乎遗漏了什么,有人能帮我吗?
提前感谢
查看代码,我发现了多个问题:
- 在多个线程中使用std::vector时,没有互斥对象->Race条件
- 分配给未来将阻止您的程序
- 您打算在未来的同一实例上多次调用
.get()
对于std::future
,只允许调用.get()
一次。如果你想多次调用它,你需要std::shared_future
,它会抛出每次访问。
那么,在访问向量之前,您应该调用.get()
吗?是的,当然。否则,就不能保证元素会在向量中。然而,您也应该为访问向量添加一些同步,因为一个线程可能会尝试访问它,而另一个线程则会创建一个新的未来,重新分配您正在访问的向量。
最后,为什么要浪费时间创建新线程?手术本身看起来很便宜。即使不是,我也只能假设你不想在那一点上阻止。不幸的是,您不能阻止阻塞,因为std::future
的Dtor在某些情况下会阻塞。
同样,使用std::shared_future
可以防止这种情况发生,因为第二个赋值可以让mFuture
忘记第一个赋值,即使没有完全执行。