云之鹰 發表於 2025-12-15 09:06:01

浅谈C++11 std::async()基础用法示例

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>​​一、核心概念​​</li><li>​​二、函数原型与启动策略​​</li><li>​​三、基础用法示例​​</li><ul class="second_class_ul"><li>​​1. 最简用法(无显式策略)​​</li><li>​​2. 显式指定启动策略​​</li></ul><li>​​四、参数传递与引用语义​​</li><ul class="second_class_ul"></ul><li>​​五、std::future 的常用接口​​</li><ul class="second_class_ul"></ul><li>​​六、异常处理​​</li><ul class="second_class_ul"></ul><li>​​七、注意事项​​</li><ul class="second_class_ul"></ul><li>​​八、典型应用场景​​</li><ul class="second_class_ul"></ul><li>​​总结​​</li><ul class="second_class_ul"></ul></ul></div><p>在 C++11 中引入的 <code>std::async</code>是一个用于异步执行任务的工具,它简化了多线程编程的复杂度,通过返回 <code>std::future</code>对象实现对异步任务结果的获取。</p>
<p class="maodian"></p><h2>​​一、核心概念​​</h2>
<p><code>std::async</code>用于启动一个异步任务(可能在独立线程中执行),并返回一个 <code>std::future</code>对象,通过该对象可以:</p>
<ul><li>阻塞等待任务完成并获取返回值(<code>future::get()</code>);</li><li>查询任务状态(<code>future::valid()</code>、<code>future::wait_for()</code>等);</li><li>异常传递(任务中的异常会延迟到 <code>get()</code>时抛出)。</li></ul>
<p class="maodian"></p><h2>​​二、函数原型与启动策略​​</h2>
<p><code>std::async</code>的声明如下:</p>
<div class="jb51code"><pre class="brush:cpp;">template&lt; class Function, class... Args &gt;
std::future&lt;typename std::result_of&lt;Function(Args...)&gt;::type&gt;
    async( Function&amp;&amp; f, Args&amp;&amp;... args );

template&lt; class Function, class... Args &gt;
std::future&lt;typename std::result_of&lt;Function(Args...)&gt;::type&gt;
    async( std::launch policy, Function&amp;&amp; f, Args&amp;&amp;... args );</pre></div>
<p>其中第二个模板参数是​<strong>​启动策略​</strong>​(<code>std::launch</code>枚举),控制任务的执行方式:</p>
<table><thead><tr><th><p>策略</p></th><th><p>说明</p></th></tr></thead><tbody><tr><td><p>std::launch::async</p></td><td><p>强制在新线程中异步执行任务(类似 std::thread直接启动)。</p></td></tr><tr><td><p>std::launch::deferred</p></td><td><p>延迟执行:任务不会立即启动,直到调用 future.get()或 wait()时才在当前线程同步执行。</p></td></tr><tr><td><p>默认策略(无显式指定)</p></td><td><p>实现定义(通常是 `async</p></td></tr></tbody></table>
<p class="maodian"></p><h2>​​三、基础用法示例​​</h2>
<p class="maodian"></p><h3>​​1. 最简用法(无显式策略)​​</h3>
<div class="jb51code"><pre class="brush:cpp;">template&lt; class Function, class... Args &gt;
std::future&lt;typename std::result_of&lt;Function(Args...)&gt;::type&gt;
    async( Function&amp;&amp; f, Args&amp;&amp;... args );

template&lt; class Function, class... Args &gt;
std::future&lt;typename std::result_of&lt;Function(Args...)&gt;::type&gt;
    async( std::launch policy, Function&amp;&amp; f, Args&amp;&amp;... args );</pre></div>
<ul><li><code>std::async(compute, 2, 3)</code>启动异步任务,传递函数 <code>compute</code>和参数 <code>2, 3</code>。</li><li><code>future.get()</code>阻塞主线程,直到任务完成并返回结果。</li></ul>
<p class="maodian"></p><h3>​​2. 显式指定启动策略​​</h3>
<div class="jb51code"><pre class="brush:cpp;">// 强制异步执行(新线程)
auto future_async = std::async(std::launch::async, compute, 2, 3);

// 延迟执行(当前线程同步执行)
auto future_deferred = std::async(std::launch::deferred, compute, 2, 3);

future_async.get(); // get()阻塞等待
future_deferred.get(); // 此时在当前线程同步执行 compute(2,3)</pre></div>
<p class="maodian"></p><h2>​​四、参数传递与引用语义​​</h2>
<p><code>std::async</code>支持传递任意可调用对象(函数、Lambda、函数对象等)和参数。若需传递引用,需用 <code>std::ref</code>包装:</p>
<div class="jb51code"><pre class="brush:cpp;">#include &lt;functional&gt;

void modify(int&amp; value) {
    value = 100;
}

int main() {
    int x = 0;
    // 错误:直接传递引用会被复制(值语义)
    // auto future = std::async(modify, x);

    // 正确:用 std::ref 传递引用
    auto future = std::async(modify, std::ref(x));
    future.get();
    std::cout &lt;&lt; x &lt;&lt; std::endl; // 输出 100(x 被修改)

    return 0;
}</pre></div>
<p class="maodian"></p><h2>​​五、std::future 的常用接口​​</h2>
<p><code>std::async</code>返回的 <code>std::future</code>提供以下关键方法:</p>
<table><thead><tr><th><p>方法</p></th><th><p>说明</p></th></tr></thead><tbody><tr><td><p>get()</p></td><td><p>阻塞直到任务完成,返回结果(或抛出任务中的异常);只能调用一次。</p></td></tr><tr><td><p>wait()</p></td><td><p>阻塞直到任务完成;可多次调用。</p></td></tr><tr><td><p>wait_for(timeout)</p></td><td><p>阻塞最多 timeout时间,返回 std::future_status(ready/timeout/deferred)。</p></td></tr><tr><td><p>wait_until(timepoint)</p></td><td><p>阻塞直到指定时间点。</p></td></tr><tr><td><p>valid()</p></td><td><p>检查 future是否关联有效结果(未调用 get()时为 true)。</p></td></tr><tr><td><p>share()</p></td><td><p>转换为 std::shared_future(允许多个对象共享结果)。</p></td></tr></tbody></table>
<p class="maodian"></p><h2>​​六、异常处理​​</h2>
<p>异步任务中抛出的异常会被 <code>std::future</code>捕获,直到调用 <code>get()</code>时重新抛出:</p>
<div class="jb51code"><pre class="brush:cpp;">int risky_compute(int x) {
    if (x &lt; 0) throw std::runtime_error("x is negative");
    return x * 2;
}

int main() {
    auto future = std::async(risky_compute, -1);
    try {
      int result = future.get(); // 抛出 std::runtime_error
    } catch (const std::exception&amp; e) {
      std::cerr &lt;&lt; "Error: " &lt;&lt; e.what() &lt;&lt; ""; // 捕获异常
    }
    return 0;
}</pre></div>
<p class="maodian"></p><h2>​​七、注意事项​​</h2>
<ol><li><p>​<strong>​生命周期管理​</strong>​:</p>
<p><code>std::future</code>析构时,若任务未完成且未被 <code>get()</code>或 <code>wait()</code>,可能导致程序终止(取决于实现)。若需共享结果,使用 <code>std::shared_future</code>。</p></li><li><p>​<strong>​线程复用​</strong>​:</p>
<p><code>std::async</code>不保证任务一定在新线程中执行(尤其是 <code>deferred</code>策略或编译器优化),依赖具体实现。</p></li><li><p>​<strong>​性能开销​</strong>​:</p>
<p>相比手动管理 <code>std::thread</code>,<code>std::async</code>自动管理线程生命周期,但频繁创建小任务可能有额外开销(适合中高耗时任务)。</p></li></ol>
<p class="maodian"></p><h2>​​八、典型应用场景​​</h2>
<ul><li>​<strong>​并行计算​</strong>​:同时执行多个独立任务(如图像处理中的多区域计算)。</li><li>​<strong>​异步IO​</strong>​:发起IO操作后异步等待结果,避免阻塞主线程。</li><li>​<strong>​任务编排​</strong>​:结合 <code>std::future::wait_for</code>实现超时控制(如监控任务是否超时)。</li></ul>
<p class="maodian"></p><h2>​​总结​​</h2>
<p><code>std::async</code>是 C++11 中简化异步编程的核心工具,通过 <code>std::future</code>提供结果获取和状态查询能力。合理使用其启动策略和异常处理机制,可有效提升代码的并发性能和可维护性。</p>
<p>到此这篇关于浅谈C++11 std::async()基础用法示例的文章就介绍到这了,更多相关C++11 std::async()内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>c++11之std::async&nbsp;和std::thread的区别小结</li><li>C++11异步与通信之std::async的使用</li><li>C++ std::async的使用总结</li><li>c++11多线程编程之std::async的介绍与实例</li><li>C++中的std::async()详解</li><li>C++11中多线程编程-std::async的深入讲解</li><li>C++11中std::async的使用详解</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 浅谈C++11 std::async()基础用法示例