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

unftdfkk  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(140)

当我运行下面的代码时,

#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;
}

我得到了以下输出。

do some on main thread
sub : 139899103246080
main: 139899103250240

运行演示:https://godbolt.org/z/c9WedY4oq
这与我预期的行为相同。"do some on main thread"首先输出,因为std::async()创建的子线程在线程开始后等待1秒。
到目前为止,一切顺利。
然而,当我删除变量fut时,我得到了奇怪的行为。此代码仅用于实验目的

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

int main() {
    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;
    
    std::cout << "main: " << std::this_thread::get_id() << std::endl;
}

下面是输出:

sub : 139716056966912
do some on main thread
main: 139716056971072

运行演示:https://godbolt.org/z/obzzceGGr
主线程似乎要等到完成子线程才会输出"在主线程上做一些事情"。
我想知道为什么会发生这种行为。
我收到了警告信息":6:5:警告:忽略使用"nodiscard"属性[-Wunused-result]"声明的函数的返回值。自C++20起,添加了nodiscard属性。请参见https://en.cppreference.com/w/cpp/thread/async
我猜是因为忽略了std::async()的返回值,所以得到了一个未定义的行为,但是到目前为止,我找不到这样的文档。

nkcskrwz

nkcskrwz1#

在第二种情况下,仍将创建并返回std::future对象。
该对象是短暂的,将立即被销毁,这就导致了您的问题,因为the std::futuredestructor将等待未来准备就绪后才继续销毁。

相关问题