在主函数以外的函数中使用 std::async 时的作用域块

Posted

技术标签:

【中文标题】在主函数以外的函数中使用 std::async 时的作用域块【英文标题】:scope block when use std::async in function other than the main function 【发布时间】:2019-01-08 13:21:28 【问题描述】:

当在除 Main 函数之外的其他函数中使用它时,我对 st::async 有一些问题, 假设,我有像流动这样的功能:

void printData() 

   for (size_t i = 0; i < 5; i++)
    
        std::cout << "Test Function" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    


void runningAsync()

    auto r = std::async(std::launch::async, test);


int main()

    runningAsync();

    std::cout << "Main Function" << std::endl;

这段代码的输出是:

Test Function
Test Function
Test Function
Test Function
Test Function
Main Function

这样不好,主线程等待其他线程结束。

我希望 runningAsync() 函数在其他线程中运行,同时在屏幕上打印主线程中的“Main Function”,这可以通过 std::thread 实现。

这种方式可以同时运行这个函数吗(并发)?

【问题讨论】:

源代码不会按原样编译。使用 printData 更改测试,反之亦然。 【参考方案1】:

原因是std::async 返回一个std::future,您将其存储在auto 变量中。一旦你的 future 超出范围(在runningAsync()! 的末尾),它的析构函数就会阻塞,直到任务完成。如果您不希望这样,例如可以将未来存储在全局容器中。

【讨论】:

【参考方案2】:

这个问题的答案是:

main thread waits for std::async to complete

Can I use std::async without waiting for the future limitation?

无论谁,如果你存储 std::future 对象,它的生命周期将延长到 main 的末尾,你会得到你想要的行为。

void printData() 

   for (size_t i = 0; i < 5; i++)
    
        std::cout << "Test Function" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    


std::future<void> runningAsync()

    return std::async(std::launch::async, test);


int main()

    auto a = runningAsync();

    std::cout << "Main Function" << std::endl;

这是一个问题,因为std::future's destructor 可能会阻塞并等待线程完成。查看此链接了解更多详情

【讨论】:

源代码不会按原样编译。将test 更改为printData,反之亦然。

以上是关于在主函数以外的函数中使用 std::async 时的作用域块的主要内容,如果未能解决你的问题,请参考以下文章

std::async 与共享指针模板化成员函数

std::async 可以与模板函数一起使用吗

在 Visual Studio 中,与 std::async 一起使用时未调用“thread_local”变量的析构函数,这是一个错误吗?

为啥 std::async 不能与接收抽象类引用作为参数的函数一起使用?

C++ 从 std::async 函数读取命名空间中的全局变量标志

析构函数和异步任务