You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::async实参的生命周期是怎样的?

关于std::async实参与future对象共享生命周期的测试发现

我最近做了个测试,发现一个挺有意思的细节:通过std::async执行函数时,传递的实参会和返回的std::future对象共享生命周期。也就是说,这些实参不会在std::async调用结束后立刻销毁,而是会一直存活到对应的future对象被销毁、或者调用了get()/wait()等完成操作之后。

下面是我用来验证这个现象的完整示例代码:

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

struct S {
    S() { std::cout << "S() " << (uintptr_t)this << std::endl; }
    S(S&& s) { std::cout << "S(&&) " << (uintptr_t)this << std::endl; }
    S(const S& s) = delete;
    ~S() { std::cout << "~S() " << (uintptr_t)this << std::endl; }
};

void func(S s) {
    std::cout << "func executing" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main() {
    std::cout << "Creating S instance\n";
    S s;
    std::cout << "Calling std::async\n";
    auto fut = std::async(std::launch::async, func, std::move(s));
    std::cout << "std::async called, main continues\n";
    // 若注释掉下面的fut.get(),会看到实参的析构会在fut销毁时才触发
    // fut.get();
    std::cout << "Main about to exit scope\n";
}

输出分析(未调用fut.get()的情况):

Creating S instance
S() 0x7ffeefbff5e8
Calling std::async
S(&&) 0x55f8a7c2c2a0
std::async called, main continues
Main about to exit scope
~S() 0x55f8a7c2c2a0
~S() 0x7ffeefbff5e8

从输出能明确看到:

  • main中创建的S实例(地址0x7ffeefbff5e8)被移动到了std::async内部的实参对象(地址0x55f8a7c2c2a0)
  • 这个被移动后的实参并没有在std::async调用结束后立刻销毁,而是等到main块结束、fut对象被销毁时才执行析构。

如果我们调用fut.get(),实参的析构会在get()返回后立刻发生——因为此时future的任务已经完成,不再需要持有实参的生命周期了。

这个细节需要特别注意:如果你传递的实参是持有文件句柄、内存等资源的对象,它的生命周期会和future绑定,可能会导致意外的资源占用,得提前做好规划。

内容的提问来源于stack exchange,提问作者Kentzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:14:18