如果返回值不是由左值保存,为什么主线程会等待 std::async() 创建的线程?

Tak*_*ndo 3 c++ multithreading asynchronous future

当我运行以下代码时,

#include <thread>
#include <iostream>
#include <future>

int main() {
    auto fut = std::async(
        std::launch::async, 
        []{
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << "sub : " << std::this_thread::get_id() << std::endl;
        }
    ); 

    std::cout << "do some on main thread" << std::endl;
    
    fut.get();

    std::cout << "main: " << std::this_thread::get_id() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出。

do some on main thread
sub : 139899103246080
main: 139899103250240
Run Code Online (Sandbox Code Playgroud)

运行演示:https://godbolt.org/z/c9WedY4oq

这与我预期的行为相同。“在主线程上执行一些操作”首先输出,因为创建的子线程在std::async()线程开始时等待 1 秒。

到目前为止,一切都很好。


然而,当我删除变量时fut,我得到了奇怪的行为。注意:此代码仅用于实验目的

do some on main thread
sub : 139899103246080
main: 139899103250240
Run Code Online (Sandbox Code Playgroud)

这是输出:

sub : 139716056966912
do some on main thread
main: 139716056971072
Run Code Online (Sandbox Code Playgroud)

运行演示: https: //godbolt.org/z/obzzceGGr

主线程似乎要等到子线程完成后才输出“在主线程上做一些事情”。

我想知道为什么会出现这种行为。

我收到警告消息“:6:5:警告:忽略使用“nodiscard”属性声明的函数的返回值[-Wunused-result]”。从C++20开始,添加了nodiscard属性。请参阅https://en.cppreference.com/w/cpp/thread/async

我猜想由于忽略了返回值,我得到了未定义的行为std::async(),但到目前为止我找不到这样的文档。

Som*_*ude 8

在第二种情况下,std::future仍然会创建并返回一个对象。

该对象是短暂的,将立即被销毁,这会导致您的问题,因为析构函数std::future 等待未来准备好,然后再继续销毁。