实施未来::则(),相当于在C异步执行++ 11 [英] implementing future::then() equivalent for asynchronous execution in c++11

查看:131
本文介绍了实施未来::则(),相当于在C异步执行++ 11的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对函数的实现了几个问题,然后()的<一个href=\"http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Herb-Sutter-Concurrency-and-Parallelism\">Herb萨特的谈话。此功能用于连锁异步操作,参数˚F是一个操作一个未来和参数是W 是作品进行此项操作(拉姆达)。

 模板&LT; typename的笏,typename的工作与GT;
然后自动(FON楼工作W) - &GT;未来&LT; decltype(W(f.get()))&GT;
{
    返回异步([=] {W(f.get());});
}

应用的一个例子是:

 的std ::未来&LT; INT&GT; F =的std ::异步([] {
        的std :: this_thread :: sleep_for(性病::时辰::微秒(200));
        返回10;
    });    汽车F2 =则(性病::移动(F),[](int i)以{
        返回2 * I;
    });

在主线程派生的任务,但不等待任何人来完成。

首先,未来&LT; T&GT; 没有一个拷贝构造函数。这意味着,该建议的实施可与 shared_future&LT的前提下使用; T&GT; 除非我们改变异步()调用 未来进入拉姆达。 <一href=\"http://stackoverflow.com/questions/14200678/c11-async-continuations-or-attempt-at-then-semantics/14200861#comment20089049_14200861\">This SO质疑建议这样做的一种方式,但似乎太复杂了。我重新实现的功能,我想知道我的code是否是正确的还是我错过了什么...

其次,被传递到则()函数可能是无效,所以我们实际上需要2个未来的实现则(),对不对?一位期货返回 T ,一个用于期货返回无效

最后,应该的体内拉姆达则()没有return语句,这样我们实际上可以返回值回来?如果没有return语句,然后返回未来&LT;无效&GT; ,对

我试图解决以上几点,这就是我想出了。难道是正确的吗?

 模板&LT; typename的T,typename的工作与GT;
汽车则(未来&LT; T&GT; F,工作W) - &GT;未来&LT; decltype(W(f.get()))&GT;
{
    返回异步([](未来&LT; T&GT; F,工作W)
                      {返回W(f.get()); },移动(F),移动(W));
}模板&LT; typename的工作与GT;
汽车则(未来&LT;无效&GT; F,工作W) - &GT;未来&LT; decltype(W())&GT;
{
    返回异步([](未来&LT;无效&GT; F,工作W)
                      {f.wait();返回W(); },移动(F),移动(W));
}


解决方案

为了简化界面,我就隐藏无效实施内部问​​题,同样什么香草与他的并发&LT做; T&GT; 的实施。相反,具有2 然后的实施,宣告一个辅助函数 get_work_done 2个实现:

 模板&LT; typename的T,typename的工作与GT;
汽车get_work_done(未来&LT; T&GT;&安培; F,工作和放大器; W) - &GT; decltype(W(f.get()))
{返回W(f.get());}模板&LT; typename的工作与GT;
汽车get_work_done(未来&LT;无效&GT;&安培; F,工作和放大器; W) - &GT; decltype(W())
{f.wait();返回W();}

然后让模板参数检测照顾其余的:

 模板&LT; typename的T,typename的工作与GT;
汽车则(未来&LT; T&GT; F,工作W) - &GT;未来&LT; decltype(W(f.get()))&GT;
{
    返回异步([](未来&LT; T&GT; F,工作W)
                      {返回get_work_done(F,W); },移动(F),移动(W));
}

I have a few questions about the implementation of the function then() in Herb Sutter's talk. This function is used to chain asynchronous operations, the parameter f is a future from one operation and the parameter w is the 'work' for this operation (lambda).

template <typename Fut, typename Work>
auto then(Fut f, Work w) -> future<decltype(w(f.get()))>
{
    return async([=]{ w(f.get()); });
}

An example of application would be:

    std::future<int> f = std::async([]{
        std::this_thread::sleep_for(std::chrono::microseconds(200));
        return 10;
    });

    auto f2 = then(std::move(f), [](int i){
        return 2 * i;
    });

The main thread spawns the tasks but does not wait for any of them to finish.

Firstly, future<T> does not have a copy constructor. This means, that the suggested implementation can be only used with shared_future<T> unless we change the call to async() to move the future into the lambda. This SO question suggested a way of doing it but it seems too complicated. I re-implemented the function and I am wondering whether my code is correct or whether I missed something...

Secondly, the future that is passed to the then() function might be void so we actually need 2 implementations of then(), right? One for futures returning T and one for futures returning void.

Lastly, should the lambda inside the body of then() not have a return statement so that we can actually return the value back? Without the return statement, then returns future<void>, right?

I tried to address the above points and this is what I came up with. Is it correct?

template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
    return async([](future<T> f, Work w)
                      { return w(f.get()); }, move(f), move(w));
}

template <typename Work>
auto then(future<void> f, Work w) -> future<decltype(w())>
{
    return async([](future<void> f, Work w)
                      { f.wait(); return w(); }, move(f), move(w));
}

解决方案

In order to simplify the interface, I would "hide" the void problem inside the implementation, similarly to what Herb did with his concurrent<T> implementation. Instead of having 2 then implementations, declare a helper function get_work_done with 2 implementations:

template <typename T, typename Work>
auto get_work_done(future<T> &f, Work &w)-> decltype(w(f.get()))
{return w(f.get());}

template <typename Work>
auto get_work_done(future<void> &f, Work &w)-> decltype(w())
{f.wait(); return w();}

And then let template parameter detection take care of the rest:

template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
    return async([](future<T> f, Work w)
                      { return get_work_done(f,w); }, move(f), move(w));
}

这篇关于实施未来::则(),相当于在C异步执行++ 11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆