使用 std::future 和 std::async 的依赖求解器

Posted

技术标签:

【中文标题】使用 std::future 和 std::async 的依赖求解器【英文标题】:Dependency solver using std::future and std::async 【发布时间】:2015-12-09 18:31:10 【问题描述】:

我正在尝试使用std::futurestd::async 实现一个简单的依赖关系求解器。目前我不明白是否有可能做到这一点。问题是,我们可以通过(尚不可用)futureasync 通话吗?如果没有,实际上可以做些什么来让带有一些尚未准备好输入的函数链相互调用?也许,可以覆盖传递给延迟异步的值?

可能我的描述难以理解,所以举个例子:

#include <iostream>
#include <future>
#include <map>

using namespace std;

int adder(future<int> a, future<int> b) 
    return a.get() + b.get();


int main() 
    map<char, future<int>> scheme;

    scheme['c'] = future<int>(async(launch::deferred, []  return 1;));
    scheme['a'] = future<int>(async(launch::deferred, adder, move(scheme['b']), move(scheme['c'])));
    scheme['b'] = future<int>(async(launch::deferred, []  return 3;));

    cout << scheme['a'].get() << endl;

我们应该有这样的方案:

c
  \
    a ----- result
  /
b

4 的结果。 此代码失败:move 只取一个空的future 并将其传递给adder。如果我们用'a''b' 交换行,它会正常工作,但这样我们应该已经知道依赖关系了。

【问题讨论】:

【参考方案1】:

使用承诺。或许还有未来的未来。

template<class T>
struct problem 
  std::promise<std::shared_future<T>> p;
  std::shared_future<std::shared_future<T>> f;
  problem():f(p.get_future())
  template<class W, class...Args>
  void set(W&&work, Args&&...args)
    p.set_value(std::async(std::launch::deferred, std::forward<W>(work), std::forward<Args>(args)...));
  
  T get()
    return f.get().get();
  
;

int adder(problem<int>& a, problem<int>& b) 
  return a.get() + b.get();

int main() 
  std::map<char, problem<int>> scheme;

  scheme['c'].set([]  return 1; );
  scheme['a'].set(adder, std::ref(scheme['b']), std::ref(scheme['c']));
  scheme['b'].set([]  return 3; );

  std::cout << scheme['a'].get() << '\n';

可能有更简单的方法。

live example.

【讨论】:

谢谢,它确实有效!我几乎了解未来的未来和未来的承诺背后的所有魔力。这是代码的工作版本:gist.github.com/JIghtuse/25960e886d97ac885f67 @JIghtuse 添加了一个实例。我不确定我是否可以消除未来的未来问题;也许通过在稍后设置的problem 中显式存储std::function,然后创建延迟调用该函数的std::shared_future?嗯,我认为这实际上会起作用。但是,如果存在周期,事情可能会变得棘手。

以上是关于使用 std::future 和 std::async 的依赖求解器的主要内容,如果未能解决你的问题,请参考以下文章

c++ 中的 std::promise 和 std::future

为啥 std::future 从 std::packaged_task 和 std::async 返回不同?

有条件的 std::future 和 std::async

std::future的基本用法

C++ std::future与promise(异步回调异步调用)

C++ std::future与promise(异步回调异步调用)