C++ 多个 return 来自使用 promise、future 的线程的值?

C++ multiple return values from thread using promise, future?

我想做的是 return 每个线程的一个值。但是,它有此异常消息。

libc++abi.dylib: terminating with uncaught exception of type std::__1::future_error: Operation not permitted on an object without an associated state.

代码如下所示。

vector<thread> t;
promise<class_name> promises;
vector<future<class_name>> futures;

for(int i = 0; i < NumberOfThreads; i++)
{
    futures.push_back(promises.get_future());
    t.push_back(thread(MyFunction ,i , pointList, std::move(promises)));
}

MyFunction 看起来像这样。

void MyFunction(int index, const vector<Point>& pointList, promise<class_name>&& p)
{
....
p.set_value(classObj);
}

如果我使用线程,那么它可以正常工作而不会出现异常消息。

有解决这个问题的想法吗?

将诺言移至其线程后,请勿重复使用它。将 promise 移到循环体内,您的代码应该 运行 没问题:

vector<thread> t;
vector<future<class_name>> futures;

for(int i = 0; i < NumberOfThreads; i++)
{
    promise<class_name> p;
    futures.push_back(p.get_future());
    t.push_back(thread(MyFunction ,i , pointList, std::move(p)));
}

当你这样做时

std::promise<T> p;

您使用 空共享状态 创建承诺 p。这不同于没有共享状态

当你从一个承诺中移动时,共享状态被获取。所以

std::promise<T> p2=std::move(p);

现在 p 没有共享状态 ,并且 p2空共享状态 p 是用.

构建的

当您 push_back 进入容器时,它会执行类似于上述构造的操作(可能会重复)。

p 现在是一个极其无用的变量。它可以被销毁,也可以被赋值,也可以被 swap 与另一个 promise 结合。 p 上的所有其他操作都是非法的。

函数如:

template<class T>
void reset_promise( std::promise<T>& p ) {
  p = std::promise<T>{};
}

可用于为 p 提供一个空的共享状态。但是,考虑到 promise 的典型使用模式,我看不出有什么意义。

std::vector<std::thread> t;
std::promise<class_name> promises;
std::vector<std::future<class_name>> futures;

for(int i = 0; i < NumberOfThreads; i++)
{
  futures.push_back(promises.get_future());
  t.push_back(thread(MyFunction ,i , pointList, std::move(promises)));
}

在第一个循环中,您离开了 promise。在第二个循环中,您尝试 get_future 从一个被移出的承诺中,而您的代码正在做一些非法的事情。

或者:

for(int i = 0; i < NumberOfThreads; i++)
{
  futures.push_back(promises.get_future());
  t.push_back(thread(MyFunction ,i , pointList, std::move(promises)));
  reset_promise(promises);
}

如果你真的想重用promises变量,或者

std::vector<std::thread> t;
std::vector<std::future<class_name>> futures;

for(int i = 0; i < NumberOfThreads; i++)
{
  std::promise<class_name> promises;
  futures.push_back(promises.get_future());
  t.push_back(thread(MyFunction ,i , pointList, std::move(promises)));
}

将确保您在使用时拥有有效的 promise。在这种情况下,第二种可能是最好的:在小范围内构建、使用和丢弃承诺。

基本上,promises 是创建、提取未来、将承诺移动到需要的地方、丢弃模式的最佳选择。拥有共享状态的移出承诺会消耗资源(因为共享状态通常存储在堆中),所以他们没有这样做。