C++11 异步编程之std::async和std::future

C++11中提供的异步任务高级抽象,包含在 < future>头文件中,它能让我们方便的实现异步地执行一个耗时任务,并在需要的时候获取其结果。 
我举几个例子: 
1.批量拷贝/下载文件; 
2.进行一个复杂的计算; 
3.执行多个嵌套的SQL查询语句; 
在实际开发中,计算机进行这些操作的时候,都需要在一定时间后才能返回结果,这个时候就需要我们用异步。比起直接使用std::thread 相比,std::async和std::future有以下优势: 
1.std::async 返回的future对象,可以方便地等待callable对象执行完成并获取其返回值; 
2.能从实现库的一些高级功能中获益,比如线程池等,并大大减少异常的产生。 
我们来看下实际代码例子future

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

bool is_prime(int x)
{
    for(int i=2;i<x;i++)
    {
        if(x%i==0)
            return false;

        return true;
    }
}

int main()
{
    std::future <bool> fut = std::async(is_prime,4444444444444444443);

    std::cout<<"wait,Checking";
    std::chrono::milliseconds span(10);
    while(fut.wait_for(span)==std::future_status::timeout)
        std::cout<<'.'<<std::flush;
        bool x = fut.get();
        std::cout<<"\n4444444444444444443"<<(x?" is":"is not") << " prime.\n";
        return 0;
}

std::future 可以用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段。std::future 通常由某个 Provider 创建,你可以把 Provider 想象成一个异步任务的提供者,Provider 在某个线程中设置共享状态的值,与该共享状态相关联的 std::future 对象调用 get(通常在另外一个线程中) 获取该值,如果共享状态的标志不为 ready,则调用 std::future::get 会阻塞当前的调用者,直到 Provider 设置了共享状态的值(此时共享状态的标志变为 ready),std::future::get 返回异步任务的值或异常(如果发生了异常)。 
函数async()用法很像thread,同样可以启动一个线程,但该函数返回的是一个future对象而非thread对象,因此它的侧重点在于计算结果而非过程。接下来看下thread代码和async代码之间的转换:

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

using namespace std;

int main(int argc, char const *argv[]) {


    thread t([]{cout<<"hello"<<endl;});
    t.join();

    return 0;
}

上面的代码等同于:

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

using namespace std;


int main(int argc, char const *argv[]) {

    auto f =async([]{cout<<"hello"<<endl;});
    f.wait();

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lx17746071609/p/11137198.html