当前位置: 首页 > 知识库问答 >
问题:

等待多个未来?

邬英武
2023-03-14

我想运行相同类型的任务(工作线程),但一次不超过一定数量的任务。当任务完成时,其结果是新任务的输入,然后可以启动该任务。

有没有好的方法可以在C 11中使用异步/未来范式来实现这一点?

乍一看,它看起来很简单,你只是生成多个任务:

std::future<T> result = std::async(...);

然后,运行result.get()以获取任务的异步结果。

然而,这里的问题是,未来的对象必须存储在某种队列中并一个接一个地等待。但是,可以一遍又一遍地迭代未来的对象,检查它们中的任何一个是否准备好了,但是由于不必要的CPU负载,这是不需要的。

是否有可能以某种方式等待一个给定集合中的任何未来准备好并得到它的结果?

到目前为止,我能想到的唯一选择是没有任何异步/未来的老式方法。具体而言,生成多个工作线程,并在每个线程结束时将其结果推入受互斥锁保护的队列,通过条件变量通知等待的线程队列已更新更多结果。

有没有其他更好的异步/未来解决方案

共有3个答案

胥博文
2023-03-14

Facebook的愚蠢已经收集了所有的期货,我还没有尝试过,但看起来很有希望。

缪坚诚
2023-03-14

你可以创建“第一代”的所有未来,并将所有这些未来交给你的第二代任务,然后他们将自己等待他们的输入。

仰成天
2023-03-14

C 11中的线程支持只是第一次,虽然std::future很重要,但它还不支持多次等待。

然而,你可以相对低效地伪造它。您最终为每个<code>std::future</code>(哎哟,非常昂贵)创建了一个助手线程,然后将它们的“this<code>future

此系统中的 std::future 不会添加太多功能,并且让任务直接声明它们已准备就绪并将其结果粘贴到上述队列中会更有效。如果采用此路由,则可以编写与 std::async 或 std::thread 模式匹配的包装器,并返回表示队列消息的 std::future 类似对象。这基本上涉及重新实现并发库的一部分。

如果您想继续使用std::future,您可以创建shared_futures,并让每个依赖任务依赖于shared_futures的集合:即在没有中央调度程序的情况下进行。这不允许像中止/关闭消息这样的事情,我认为这对于健壮的多线程任务系统至关重要。

最后,您可以等待C 2x,或者每当并发TS被合并到标准中时,为您解决问题。

 类似资料:
  • 问题内容: 请考虑以下代码片段: 这是在小程序中添加一个标签,该标签显示了Worker线程的一些中间结果(使用发布/处理方法)。最后,标签从小程序的窗格中删除。我的问题是,如何创建多个标签,每个标签都有自己的Worker线程,并在完成标签后将其删除? 提前致谢。 更新: 我希望这可以澄清我的问题。我希望在所有工作人员都完成任务后立即删除所有标签,而不是在每个工作人员都完成之后立即删除。 更新2:

  • 请考虑以下代码片段: 下面是向小程序添加一个标签,该标签显示工作线程的一些中间结果(使用发布/处理方法)。最后,标签将从小程序的窗格中移除。我的问题是,我如何创建几个标签,每个标签都有自己的工作线程,并在全部完成后删除它们? 提前感谢。 更新: 我希望这能澄清我的问题。我希望在所有工人完成任务后,而不是在每个工人完成任务后立即移除所有标签。 更新2: 下面的代码似乎正在做我需要的事情。请评论我的做

  • 问题内容: 如何更改以下代码,以触发两个异步操作并有机会同时运行? 我需要做这样的事情吗? 问题答案: TL; DR 不要在获得承诺的问题中使用模式,而是分别等待它们;而是使用(至少现在): 虽然您的解决方案 确实 并行运行这两个操作,但如果两个诺言都被拒绝,它就无法正确处理拒绝。 细节: 您的解决方案并行运行它们,但始终等待第一个完成,然后再等待第二个。 如果您只想启动它们,并行运行它们,并获得

  • 问题内容: 我如何更改以下代码,以触发两个异步操作并有机会同时运行? 我需要做这样的事情吗? 问题答案: TL; DR 不要在获得承诺的问题中使用模式,而是分别等待它们;而是使用(至少现在): 虽然您的解决方案确实并行运行这两个操作,但是如果两个诺言都被拒绝,它就无法正确处理拒绝。 细节: 您的解决方案并行运行它们,但始终等待第一个完成,然后再等待第二个。如果您只想启动它们,并行运行它们,并获得两

  • 问题内容: 我通过将操作拆分为可用的确切内核数来并行化操作,然后通过启动相同数量的AsyncTask,对数据的不同部分执行相同的操作。 我正在使用以并行化它们的执行。 我想知道每个线程何时完成其工作,以便结合所有结果并执行进一步的操作。 我能怎么做? 问题答案: 您还可以简单地将共享库中的计数器递减作为的一部分。由于在同一线程(主线程)上运行,因此您不必担心同步。 更新1 共享对象可能看起来像这样

  • 问题内容: 我正在寻找一种方法来异步执行go中的两个函数,该函数返回不同的结果和错误,等待它们完成并打印两个结果。另外,如果一个函数返回错误,我不想等待另一个函数,只打印错误。例如,我具有以下功能: 这里https://play.golang.org/p/-8StYapmlg是我是如何实现它,但是它有太多的代码,我想。可以通过使用interface {}来简化它,但是我不想这样。我想要更简单的东西