首页 > 技术文章 > C++ async 函数的使用

alix-1988 2021-06-10 21:01 原文

C++11中的std::async是个模板函数。std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对象。Fn返回的值可通过std::future对象的get成员函数获取。一旦完成Fn的执行,共享状态将包含Fn返回的值并ready。

std::async有两个版本:

1.无需显示指定启动策略,自动选择,因此启动策略是不确定的,可能是std::launch::async,也可能是std::launch::deferred,或者是两者的任意组合,取决于它们的系统和特定库实现。

2.允许调用者选择特定的启动策略。

std::async的启动策略类型是个枚举类enum class launch,包括:

std::launch::async:异步,启动一个新的线程调用Fn,该函数由新线程异步调用,并且将其返回值与共享状态的访问点同步。

std::launch::deferred:延迟,在访问共享状态时该函数才被调用。对Fn的调用将推迟到返回的std::future的共享状态被访问时(使用std::future的wait或get函数)。

参数Fn:可以为函数指针、成员指针、任何类型的可移动构造的函数对象(即类定义了operator()的对象)。Fn的返回值或异常存储在共享状态中以供异步的std::future对象检索。

参数Args:传递给Fn调用的参数,它们的类型应是可移动构造的。

返回值:当Fn执行结束时,共享状态的std::future对象准备就绪。std::future的成员函数get检索的值是Fn返回的值。当启动策略采用std::launch::async时,即使从不访问其共享状态,返回的std::future也会链接到被创建线程的末尾。在这种情况下,std::future的析构函数与Fn的返回同步。
=============================

 

 

future<T>提供了一种异步获得线程中的函数返回值的方法 。future<T>表示一个类型为T的future值,这个值可以通过future<t>的get()函数来获取。这个值在线程开始执行时还是不可用的,是一个“未来的期望值”。get()函数是同步的,从子线程获取时阻塞当前线程,直到返回。

future<>可以被packaged_task<>和promise<>包装。

packaged_task<>包含两个基本的元素A  stored  task(即一个广义的可调用对象)和A  shared  state, 是一个泛化的可调用对象的包装器,类似于function<>,不过不能接受bind() 返回值。package_task<>包装对象得到包装对象,能够通过包装的对象的get_future() 方法返回一个future对象,借由future对象便可以异步得到调用被包装的可调用对象的返回值。

于是,可以将packaged_task<>包装的可调用对象,在另外一个线程来执行,最后通过future<>传出在执行的结果。

推荐阅读