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
。在这种情况下,第二种可能是最好的:在小范围内构建、使用和丢弃承诺。
基本上,promise
s 是创建、提取未来、将承诺移动到需要的地方、丢弃模式的最佳选择。拥有共享状态的移出承诺会消耗资源(因为共享状态通常存储在堆中),所以他们没有这样做。
我想做的是 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
。在这种情况下,第二种可能是最好的:在小范围内构建、使用和丢弃承诺。
基本上,promise
s 是创建、提取未来、将承诺移动到需要的地方、丢弃模式的最佳选择。拥有共享状态的移出承诺会消耗资源(因为共享状态通常存储在堆中),所以他们没有这样做。