实现类似于异步的功能

时间:2013-09-04 16:35:38

标签: c++ c++11

我有一个函数foo,返回futurefoo将注册一个将在foo返回后调用的回调。

future<int> foo() {
    promise<int> p;
    future<int> ret(p.get_future());
    thread(bind([] (promise<int> &&p) {
        this_thread::sleep_for(chrono::seconds(3));
        p.set_value(10);
    }, move(p))).detach();
    return move(ret);
}

int main()
{
    auto f = foo();
    cout << f.get() << endl;
    return 0;
}

但似乎std::bind将rvalue引用转发为左值引用,因此无法成功编译。有什么办法可以解决吗?


我必须编写一个丑陋的类来移动promise对象:

template<typename T>
class promise_forward {
    promise<T> promise_;

public:
    promise_forward(promise<T> &&p) : 
        promise_(move(p)) {}

    promise_forward(promise_forward<T> &&other) : 
        promise_(move(other.promise_)) {}

    operator promise<T> () {
        return move(promise_);
    }
};

future<int> foo() {
    promise<int> p;
    future<int> ret(p.get_future());
    thread(bind([] (promise<int> &&p) {
        this_thread::sleep_for(chrono::seconds(3));
        p.set_value(10);
    }, promise_forward<int>(move(p)))).detach();
    return ret;
}

int main()
{
    auto f = foo();
    cout << f.get() << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:1)

基本上,你在这里不需要std::bind(好吧,我相信如此=))。 这是一个最简单的异步任务启动器的快速草案。它几乎与你的相同,但是,只是更通用一点:它可以接受任何函数对象,并且它不那么具有侵入性:函数对象根本不了解promises或线程。

可能存在错误(我很确定它们是错误的)。而且,当然,距离std::async实现(通常不仅仅是线程启动器,但理想情况下,有一个巨大的线程管理后端),它距离很远。

#include <thread>
#include <future>
#include <iostream>
#include <chrono>


template< class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type> my_async(Function && f, Args && ... args)
{
    typedef typename std::result_of<Function(Args...)>::type ret_type;

    std::promise<ret_type> p;

    auto fut = p.get_future();


    // lambda in separate variable, just to improve readability 
    auto l = [](Function && f, Args && ... args, std::promise<ret_type> && p)
    {
        p.set_value(f(args...));
    };

    std::thread th(l, std::move(f), std::move(args...), std::move(p));

    th.detach();

    return std::move(fut);

}

int wannaRunAsync(int i)
{
    return i;
};

int main()
{

    auto fut = my_async(&wannaRunAsync, 42);

    auto fut2 = my_async([](int i) -> int { return i; }, 42);

    std::cout << fut.get() << std::endl;
    std::cout << fut2.get() << std::endl;

    std::cin.get();

    return 0;
}

我能够编译并运行它 g++-4.8clang++但是使用msvc 2012和2013预览它甚至不会编译(可能是由于错误)。

我根本没有测试过这段代码,所以要小心=)希望它有所帮助。