std::async 实现链式调用

来源:互联网 发布:阿里云 服务器 使用 编辑:程序博客网 时间:2024/06/02 23:02

    c#和java中都有直接提供方法实现异步执行一个任务,并在其执行完成后执行指定的任务。然而c++11却没有直接提供类似的实现。虽然用c++98的泛型和直接使用系统线程也能实现,不过要实现好还是很复杂。现在有了c++11,就可以用其中的 std::async 和 lambda方便地实现了。

    在前面的任务执行完成后,可能会返回一个值,也可能不会返回值,后续的任务虽然大部分情况都需要使用到返回的值但也可以选择性忽略返回值。因此提供了两个函数,一个将当前返回值传给下一个函数,另一个忽略返回值。

实现:

#ifndef __ASYNC_TASK#define __ASYNC_TASK#include <functional>#include <future>#include <utility>template <typename T>class Task;template <typename R, typename... Args>class Task < R(Args...) >{public:using return_type = R;template <typename F, typename... exArgs>auto then(F&& f, exArgs&&... args) -> Task < typename std::result_of<F(exArgs...)>::type(void) >{using thRType = typename std::result_of<F(exArgs...)>::type;auto func = std::move(m_fn);auto thFn = std::bind(std::forward<F>(f), std::forward<exArgs>(args)...);return Task<thRType(void)>([func, thFn]() mutable{func();return thFn();});}template <typename F>auto passthen(F&& f) -> Task < typename std::result_of<F(R)>::type(void) >{using thRType = typename std::result_of<F(R)>::type;auto func = std::move(m_fn);auto thFn = std::forward<F>(f);return Task<thRType(void)>([func, thFn]() mutable{return thFn(func());});}R get(){return std::async(std::launch::deferred, m_fn).get();}void wait(){std::async(std::launch::deferred, m_fn).wait();}std::future<R> async(std::launch launchmode){return std::async(launchmode, m_fn);}//constractorstemplate<typename... FnArgs>Task(const std::function<R(Args...)>& f, FnArgs&&... args){m_fn = std::bind(f, std::forward<FnArgs>(args)...);}~Task() = default;Task(Task &&other){m_fn = std::move(other.m_fn);}Task& operator=(Task &&other){m_fn = std::move(other.m_fn);return *this;}private:Task() = delete;Task(const Task&) = delete;Task& operator=(const Task&) = delete;private:std::function<R(void)> m_fn;};#endif

测试:

#include <iostream>#include "AsyncTask.h"int acallback(int sigarg){std::cout << "a callback arg:" << sigarg << std::endl;return sigarg * 2;}int bcallback(){std::cout << "b callback withoutarg:" << std::endl;return -1;}void ccallback(int sigarg){std::cout << "c callback arg:" << sigarg << std::endl;}void dcallback(){std::cout << "d callback withoutarg:" << std::endl;}void ecallback(int arg1, int arg2){std::cout << "e callback arg:" << arg1 <<',' <<arg2 << std::endl;}class callObj{public:callObj(int a, int b) : a_(a), b_(b) {}int operator()(){return a_ + b_;}~callObj() {}private:int a_;int b_;};int main(){//auto sometask1 = Task<int(int)>(acallback, 5).then(callObj(2,3));//auto sometask1 = Task<int(int)>(acallback, 5).passthen(std::bind(ecallback, 8, std::placeholders::_1));auto sometask1 = Task<int(int)>(acallback, 5).passthen([](int val) { std::cout << val << " lambda\n"; });sometask1.async(std::launch::async).get();return 0;}



0 0