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

Dependency solver using std::future and std::async

本文关键字:std 关系 依赖 async future 使用      更新时间:2023-10-16

我正在尝试使用std::futurestd::async实现一个简单的依赖关系求解器。目前我不明白这样做是否可能。问题是,我们可以将(尚未可用的)future呼叫传递给async吗?如果没有,那么实际可以做些什么来让一些尚未就绪的输入的函数链相互调用呢?也许,有可能覆盖传递给延迟异步的值?

也许我的描述令人费解,所以这里有一个例子:

#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

以及CCD_ 5。此代码失败:move只获取一个空的future并将其传递给adder。如果我们用'a''b'交换行,它会很好地工作,但这样我们就应该知道依赖关系了。

使用promise。也许还有未来的未来。

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';
}

可能有更简单的方法。

活生生的例子。