私はワーク スチール アルゴリズムを実装しており、ラッパー テンプレートへの可変引数の 1 つとしてプロミスを取る汎用関数ラッパーを作成しています。これらの関数ラッパーを使用してタスクを作成し、プロミスを使用して各ノードが依存ノードと通信できるようにしたいと考えています。各ノードは、依存ノードと約束/先物のリストを維持します。各ノードは、すべての先物が設定されているかどうかを確認することで実行できます。プロミスは、関数ラッパーがさまざまなオブジェクトを返すジョブによって異なります。1 つのアルゴリズムを、メッセージの読み取りとメッセージのデコード、オブジェクトのチェックの実行、すべてのチェックの結果の返しなどの個別の操作に分割できる場合、これらの各アクションは異なる promise (オブジェクト、ブール値、結果) を返します。
ただし、書籍C++ Concurrency in Actionには関数ラッパーの実装がありますが、このユース ケースは処理されません。オンラインの他の参考文献では、 std::promise のようなプロミスへのハードコーディングされた参照を見てきましたが、これは 1 つのタイプのみです。
誰かが次のことを達成するためにラッパーを書く方法をアドバイスできますか...
void add(int a, int b, std::promise<int>&& prms)
{
int res = a + b;
try {
prms.set_value(res);
}
catch(...)
{
prms.set_exception(std::current_exception());
}
}
int main()
{
std::promise<int> prms;
std::future<int> fut = prms.get_future();
FunctionWrapper myFunctor(a, 10, 20, std::move(prms));
// add the functor to the queue and it will be retrieved by a thread
// that executes the task. since i have the future, i can pass it to the
// dependent worknode
}
以下のようなコードを書いてみました...しかし、これを機能させるのは困難でした。
#ifndef FUNCTIONWRAPPER_HPP
#define FUNCTIONWRAPPER_HPP
template<typename F, typename R, typename... Args>
class FunctionWrapper
{
class implbase
{
public:
virtual ~implbase();
virtual R execute(Args...)=0;
};
class impl : public implbase
{
public:
impl(F&& f) : func(std::move(f)) {}
virtual R execute(Args... args) { return func(args...); }
private:
F func;
};
std::shared_ptr<impl> internalFunc;
public:
FunctionWrapper(F&& f) : internalFunc(0)
{
internalFunc = new impl<F, R, Args...>(f);
}
FunctionWrapper(const FunctionWrapper& other)
: internalFunc(std::move(other.internalFunc))
{}
~FunctionWrapper()
{
if(internalFunc)
delete internalFunc;
}
R operator()(Args... args)
{
return internalFunc->execute(args...);
}
void swap(FunctionWrapper& other)
{
impl<R, Args...>* tmp = internalFunc;
internalFunc = other.internalFunc;
other.internalFunc = tmp;
}
FunctionWrapper& operator=(const FunctionWrapper& other)
{
FunctionWrapper(other).swap(*this);
return *this;
}
FunctionWrapper& operator=(const F& f)
{
FunctionWrapper(f).swap(*this);
return *this;
}
};
#endif // FUNCTIONWRAPPER_HPP