gpt4 book ai didi

c++ - 如何在没有轮询的情况下实现 std::when_any?

转载 作者:太空狗 更新时间:2023-10-29 23:43:39 24 4
gpt4 key购买 nike

考虑 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com