是否有可能阻止一组锁/期货/任何可封锁的实体,直到其中任何一个准备就绪?我们的想法是,我们可以:
std::vector<std::future<T>> futures = ...;
auto ready_future = wait_until_an_element_is_ready(futures);
process(ready_future.get());我记得像libevent、libev和libuv这样的库具有执行IO任务的能力。但我不知道这些是否可以作为锁/期货。
我认为实现这一目标的一种方法是让期货在完成时调用一个处理程序,但同时将处理程序进行比较和交换,使其为null,这样其他期货就无法调用它。然而,这需要期货的协调,因此不能对锁进行协调。
更新:似乎有一个用于C++2x的proposal。
发布于 2017-01-15 12:31:05
如果您有boost可用,那么它的线程处理能力远远超过标准库。
这将是在c++17之后的情况,从外观上看,甚至在c++20之后。
#include <future>
#include <vector>
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp>
void wait_for_any(std::vector<boost::future<void>> & v)
{
boost::wait_for_any(std::begin(v), std::end(v));
}发布于 2017-01-15 10:11:27
备选案文1:
现在,这是不可能的,尽管,您可以通过编写自己的查找逻辑来解决这个问题。
template<typename Iterator>
Iterator find_first_ready_future(Iterator begin, Iterator end)
{
return std::find_if(begin, end, [](auto &future) { return future.wait_for(0s) == std::future_status::ready; }
}
template<typename T>
std::future<T> wait_until_an_element_is_ready(std::vector<std::future<T>> &vector)
{
assert(!vector.empty());
auto iterator = vector.end();
do
{
// force switch of threads (if you don't want a busy loop, you might want to sleep this thread)
// If reaction speed is very important, you might want to skip this first yield/sleep in the first iteration.
std::this_thread::yield();
iterator = find_first_ready_future(vector.begin(), vector.end());
} while (iterator == vector.cend());
auto result = std::move(*iterator);
vector.erase(iterator); // Remove the ready future to prepare for the next call. (You ain't allowed to call .get() twice)
return result;
}请注意,所有未来必须创建‘异步’标志,因为这将成为一个无限循环,如果他们是‘延迟’。
PS:如果您不希望它阻塞您的主线程,那么您可能希望在它自己的线程/将来执行它。
备选案文2:
另一种选择是包装你的未来来执行任务。这有点类似于future.then的提议:
template<typename T>
std::vector<std::future<void>> executeOnComplete(std::vector<std::future<T>> &&v)
{
std::vector<std::future<void>> result;
result.reserve(v.size());
for (auto &f : v)
result.emplace(std::async(std::launch::async,
[f = std::move(f)] { process(f.get()); }));
return result;
}此选项为每个未来创建一个新线程,并将阻止它直到最初的未来准备就绪为止。它伴随着创建过多线程的风险。
PS:使用一些花哨的result_of模板逻辑,您甚至可以创建返回“`process”结果的期货
https://stackoverflow.com/questions/41659539
复制相似问题