Yve*_*ves 0 c++ multithreading future set c++11
我正在使用 C++11 来做一些线程程序。
现在我遇到这样的情况:
我有一个std::set<std::future<std::string>> results存储线程的一些结果,当然所有这些线程都会返回一个字符串。
但是,当我尝试获取字符串时,出现以下错误:
将 xxx 作为 xxx 的“this”参数传递会丢弃限定符
根据此链接,我认为这是因为我试图调用属于 元素的非常量函数set。换句话说, the 的元素set是std::future<std::string>并且std::future<std::string>::get()是非常量。这就是为什么我收到这样的错误。
如果我是对的,这是否意味着我永远不能声明 astd::set<std::future>因为它get总是不可用?
这是我的代码:
set<future<string>> results;
results.insert(...); // insert some future
for(auto it = results.begin(); it != results.end();)
{
if (it->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
string tmp = it->get(); // ERROR!!!
}
}
Run Code Online (Sandbox Code Playgroud)
当考虑使用什么容器时,您应该思考“我可以用 a 来做这个吗std::vector?”。如果你的答案是否定的,你应该问“不,真的,我可以用 a 来做这个吗std::vector?”。
using namespace std::literals;
std::vector<std::future<std::string>> results;
constexpr auto threads = 10;
for (int i = 0; i < threads; ++i) {
results.push_back( std::async( std::launch::async,
[i]{
std::this_thread::sleep_for( std::chrono::milliseconds((threads-i)%(threads/3)) );
std::stringstream ss;
ss << "hello world " << i;
return ss.str();
}
) );
}
for (auto it = results.begin(); it != results.end();) {
if (it->wait_for( 0s ) == std::future_status::ready) {
std::string tmp = it->get();
std::cout << tmp << "\n";
std::swap( *it, results.back() ); // noop if already at back
if (std::next(it)==results.end()) it = results.begin(); // do this before pop back
results.pop_back(); // Or this could invalidate it
if (results.begin()==results.end()) break; // empty vector has to be caught early, as it is invalidated if vector is now empty
continue;
} else {
++it;
if (it == results.end()) it = results.begin();
continue;
}
}
Run Code Online (Sandbox Code Playgroud)
用 a 来做这件事std::set既是一个坏主意,也是不可能的主意。
这是一个坏主意,因为std::set基于节点的容器会努力维护排序顺序。我们不需要节点。我们不需要排序顺序。所以我们使用的容器比我们需要的更强大。
不可能,因为 的内容std::set在设计上是不可变的。
不可能,因为std::future没有提供operator<,也没有合理的地方可以将用户提供的比较函数挂接到它们上。
请注意,shared_futures 有一个const get()方法,因此它们可以以不可变的方式存储。但他们仍然没有为用户提供的排序操作提供“钩子”。