- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑 http://en.cppreference.com/w/cpp/experimental/when_any .以下只是一个简单和简化的实现:
#include <future>
template<typename Iterator>
auto when_any(Iterator first, Iterator last)
{
while (true)
{
for (auto pos = first; pos != last; ++pos)
{
if (pos->is_ready())
{
return std::move(*pos);
}
}
}
}
我不满意,因为它是一个无限循环的忙轮询。
有没有办法避免繁忙的轮询?
最佳答案
无轮询版本将为每个 future 启动 1 个线程,并让它们设置一个条件变量, future 就绪。
然后您“泄漏”线程,直到 future 准备就绪,同时返回一个准备就绪的事实。
这很糟糕。但是没有轮询。
为了做得更好,您需要有一个可以设置(理想情况下可以删除)的延续的 future 。然后你只要让 future 在完成时通知你,然后等待。这需要修改或书写自己的 future 。
这是连续和 when_any
都被提议用于标准化的原因之一。您将来需要它们。
现在,如果您有自己的系统,您可以将它建立在线程安全队列的基础上,而不是 future ,通过条件变量实现。这需要在“ future ”创造点上进行合作。
struct many_waiter_t {
std::mutex m;
std::condition_variable cv;
std::vector<std::size_t> index;
std::size_t wait() {
auto l = lock();
cv.wait(l, [this]{
return !index.empty();
});
auto r = index.back();
index.pop_back();
return r;
}
void set( std::size_t N ) {
{
auto l = lock();
index.push_back(N);
}
cv.notify_one();
}
};
template<class T>
std::future<T> add_waiter( std::future<T> f, std::size_t i, std::shared_ptr<many_waiter_t> waiter )
{
return std::async([f = std::move(f), waiter, i]{
auto r = f.get();
waiter.set(i);
return r;
});
}
使用一组 futures fs
,我们可以生成一个新的 futures 数组 f2s
和一个等待者,这样等待者可以是非自旋锁等待直到future 就绪,f2s
对应原来的fs
。
您可以重复等待 waiter
,直到 f2s
都准备好。
关于c++ - 如何在没有轮询的情况下实现 std::when_any?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44355747/
考虑 http://en.cppreference.com/w/cpp/experimental/when_any .以下只是一个简单和简化的实现: #include template auto w
在这里https://msdn.microsoft.com/en-us/library/jj969480.aspx 代码是这样的 template auto when_any(_Iterator _B
引自 cppref std::when_any 定义如下: template struct when_any_result { std::size_t index; Sequence
我是一名优秀的程序员,十分优秀!