xml*_*lmx 2 c++ concurrency standards multithreading c++17
请考虑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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不满意,因为它是一个无限循环中的繁忙轮询.
有没有办法避免繁忙的民意调查?
无轮询版本将在每个未来启动1个线程,并让它们设置一个条件变量,以便将来做好准备.
然后你"泄漏"线程,直到期货准备就绪,同时返回一个准备就绪的事实.
这很糟糕.但没有民意调查.
要做得更好,您需要拥有一个可以设置(并理想地删除)的延续的未来.然后你只要求期货在完成后通知你,然后等待.这需要修改或编写自己的未来.
这是延续和when_any提出标准化的原因之一.你将来需要它们.
现在,如果您拥有自己的系统,则可以将其基于线程安全队列,而不是期货,通过条件变量实现.这需要在"未来"创造时进行合作.
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;
});
}
Run Code Online (Sandbox Code Playgroud)
通过一系列期货fs,我们可以生成一个新的期货f2s和服务员数组,这样服务员可以非自旋锁等待直到未来准备好,并且f2s对应于原始fs.
您可以反复等待,waiter直到f2s全部准备就绪.
| 归档时间: |
|
| 查看次数: |
842 次 |
| 最近记录: |