等待多个未来
Waiting for multiple futures?
我想运行相同类型的任务(工作线程(,但一次不超过一定数量的任务。当任务完成时,其结果是新任务的输入,然后可以启动该任务。
有什么好方法可以在 C++11 中使用异步/未来范式来实现这一点?
乍一看,它看起来很简单,您只需生成多个任务:
std::future<T> result = std::async(...);
然后,运行 result.get()
以获取任务的异步结果。
但是,这里的问题是将来的对象必须存储在某种队列中,并逐个等待。但是,可以一遍又一遍地迭代未来的对象,检查它们中的任何一个是否已准备就绪,但由于不必要的 CPU 负载,这是不希望的。
是否有可能以某种方式等待给定集合中的任何未来准备就绪并获得其结果?
到目前为止,我能想到的唯一选择是没有任何异步/未来的老式方法。具体来说,生成多个工作线程,并在每个线程结束时将其结果推送到受互斥锁保护的队列中,通过条件变量通知等待线程队列已更新为更多结果。
有没有其他更好的异步/未来解决方案?
C++11 中的线程支持只是第一次传递,虽然std::future
摇滚,但它还不支持多次等待。
但是,您可以相对低效地伪造它。 您最终会为每个std::future
创建一个帮助线程(哎哟,非常昂贵(,然后将他们的"此future
已准备就绪"收集到同步的多生产者单使用者消息队列中,然后设置一个使用者任务来调度给定std::future
已准备就绪的事实。
此系统中的std::future
没有添加太多功能,并且让任务直接声明它们已准备就绪并将其结果粘贴到上述队列中会更有效。 如果你走这条路,你可以编写与std::async
或std::thread
模式匹配的包装器,并返回一个表示队列消息的类似std::future
的对象。 这基本上涉及重新实现并发库的一个块。
如果你想继续使用 std::future
,你可以创建 shared_future
s,并让每个依赖任务依赖于shared_future
s集:即,在没有中央调度程序的情况下执行此操作。 这不允许诸如中止/关闭消息之类的事情,我认为这对于强大的多线程任务系统至关重要。
最后,您可以等待 C++2x,或者每当并发 TS 折叠到标准中时,为您解决问题。
您可以创建">第 1 代"的所有未来,并将所有这些未来交给您的第 2 代任务,然后他们将自己等待他们的输入。
Facebook的愚蠢行为已经收集了期货上的Any/collectN/collectAll,我还没有尝试过,但看起来很有希望。
鉴于"Wating for Multiple Futures"的标题吸引了人们提出诸如"是否等待所有期货列表?您可以通过跟踪挂起的线程来充分做到这一点:
unsigned pending = 0;
for (size_t i = 0; i < N; ++i) {
++pending;
auto callPause =
[&pending, i, &each, &done]()->unsigned {
unsigned ret = each();
results[i] = ret;
if (!--pending)
// called in whatever thread happens to finish last
done(results);
return ret;
};
futures[i] = std::async(std::launch::async, each);
}
完整示例
可以将 std::experimental::when_all 与传播运算符一起使用
- 在Linux中哪里可以找到互斥、未来等的源代码
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 如何让LLDB在成功时退出,在失败时等待
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 使用 std::string () const 函数启动线程或未来
- 等待整个 omp 块完成,然后再调用第二个函数
- 提升 ASIO - io_service 不要等待连接到线程
- 如何在C++中实现带有packaged_task的异步等待循环?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- 如何等待窗口隐藏在Qt中?
- 如何在不等待检索的情况下获取C++中的内存位置?
- 等待被迷住了,没有回来
- QVTKWidget在VTK 8.1中已弃用,并将在未来的版本中删除
- 等待 WaitForMultipleObjects 窗口中的事件数量可变
- C++异步编程,如何不等待未来
- std::未来旋转等待吗
- std::未来等待毁灭
- 等待助推器asio的未来在io_service.stop()之后永远持续下去
- 等待多个未来
- 有没有办法异步等待 Boost Asio 的未来