std :: async lambda函数中局部变量的生命周期

问题描述 投票:0回答:1

在以下代码段中:

std::future<bool> result = std::async(std::launch::async, []()
{
    std::vector<char*> someLocalVariable{GottenFromSomewhere()};
    return SomeReallyLongLastingProcessingPipeline(someLocalVariable);
});

我倾向于说someLocalVariable无疑会比SomeReallyLongLastingProcessingPipeline()调用更长,即使这一切都发生在传递给std :: async的lambda中。这是真的?

我必须提到std::future是在SomeReallyLongLastingProcessingPipeline()之前构造的对象内部,并且在该函数退出之后被破坏。

c++ lambda lifetime local-variables stdasync
1个回答
2
投票

本身发布的代码本身似乎没有问题和无辜,但std::vectorchar*让我怀疑。你的评论“......但我担心的是someLocalVariable本身依赖于在所有这个片段所在的方法结束时超出范围的东西,这可能搞砸了,对吧?”强调我的怀疑:

是的someLocalVariable会比SomeReallyLongLastingProcessingPipeline更长,但不一定是你在char*指向std::vector的东西。你的问题可能就是GottenFromSomewhere,当整个lambda被执行时,它会填充你的someLocalVariable指向不活的东西。所以它可能在someLocalVariable的构造函数中存在或者可能已经“死”,SomeReallyLongLastingProcessingPipeline也是如此。

然而,如果没有完整的代码,这会让人猜测。

请改用std::vector<std::string>


来自评论的更新:

#include <iostream>
#include <future>
#include <string>
#include <vector>
#include <memory>

bool SomeReallyLongLastingProcessingPipeline(std::vector<const char*> data) {
    return data.at(0)[0] == 'L';
}

//Prefer this one
bool SomeReallyLongLastingProcessingPipeline(std::vector<std::shared_ptr<const std::string>> data) {
    return data.at(0)->find('L');
}

std::future<bool> foo() {

    auto big_string_you_wont_change_until_lambda_finished = std::make_shared<std::string>("Long long text "
                                                                  "(>should be at least several dozen kB");
    //You could also use std::shared_ptr foo{new std::string("ff")}; but make_shared is safer (exception safety)

    //beware of lambda capture, DO NOT just use [&] or [&big_string_you_wont_change_until_lambda_finished]
    //use [=] or [big_string_you_wont_change_until_lambda_finished] is ok
    std::future<bool> result = std::async(std::launch::async, [big_string_you_wont_change_until_lambda_finished]()
    {
        std::vector<const char*> someLocalVariable{big_string_you_wont_change_until_lambda_finished->c_str()};
        std::vector<std::shared_ptr<const std::string>> someBetterLocalVariable
        {big_string_you_wont_change_until_lambda_finished};

        return SomeReallyLongLastingProcessingPipeline(someLocalVariable) || //I recommend the last one
        SomeReallyLongLastingProcessingPipeline(someBetterLocalVariable);
    });
    return result;
}

int main() {

    auto future = foo();

    std::cout << future.get() << "\n";

    return 0;
}   
© www.soinside.com 2019 - 2024. All rights reserved.