【问题标题】:main thread waits for std::async to complete [duplicate]主线程等待 std::async 完成[重复]
【发布时间】:2026-02-18 16:40:01
【问题描述】:

我正在使用std::async 创建一个线程,我希望这个新线程应该单独执行并且主线程不应该等待它。但是在这里,当我调用 std::async 时,会创建一个新线程,但主线程正在等待fun() 的完成。我希望主线程并行执行而不等待fun() 完成。我该怎么做?

#include <iostream>
#include <windows.h>
#include <future>
using namespace std;



void printid()
{
   cout << "Thread id is:" << this_thread::get_id() << endl;
}

void fun(void *obj)
{

   cout<<"Entry"<<endl;
   printid();
   Sleep(10000);
   cout<<"Exit"<<endl;
}


int main()
{
    cout<<"Hello"<<endl;
    printid();
    std::async(std::launch::async, fun, nullptr);
    cout << "After call" << endl;
}

我得到了输出:

Hello
Thread id is:22832
Entry
Thread id is:13156
Exit
After call

【问题讨论】:

    标签: c++ multithreading asynchronous stdasync


    【解决方案1】:

    std::async 返回并使用std::launch::async 策略启动的std::future 对象,在销毁时阻塞,直到启动的任务完成。

    由于您没有将返回的std::future 存储在变量中,它会在语句末尾用std::async 销毁,因此,main 在任务完成之前无法继续。

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

    int main()
    {
        ...
        auto fut = std::async(std::launch::async, fun, nullptr);
        ...
    }
    

    【讨论】:

      【解决方案2】:
      std::async(std::launch::async, fun, nullptr);
      

      对返回的std::future 不做任何事情,让它被销毁。这是一个问题,因为std::future's destructor 可能会阻塞并等待线程完成。

      解决办法是在std::future 上保持一段时间,等你做完其他事情后让它销毁。

      auto locallyScopedVariable = std::async(std::launch::async, fun, nullptr);
      

      locallyScopedVariable 将在main 结束时超出范围,然后阻塞直到完成。

      请注意,这仍然可能无法达到您想要的效果。主线程可以立即将处理器让给新线程,并允许新线程在返回控制之前运行完成。可以更正代码,但仍然会导致输出不正确的版本。

      【讨论】:

        【解决方案3】:

        (1) 在多线程程序测试中,使用互斥锁保护共享资源(本例中为cout)不被不同线程同时调用。 (2) 主要检查future是否准备好,你也可以做一个超时。

        void print_id() 
        {
            lock_guard<mutex> locker(mutex_);
            cout << "Thread id is:" << this_thread::get_id() << endl;
        }
        
        void print( string str) 
        {
            lock_guard<mutex> locker(mutex_);
            cout << str << '\n';
        }   
        
        bool fun(void *obj)
        {
           print("Entry");
           printid();
           Sleep(10000);
           print("Exit");
           return true;
        }
        
        
        int main()
        {
            print("Hello");
            printid();
            std::future<bool> fut = std::async(std::launch::async, fun,nullptr);
            while(!fut->_Is_ready() )
            {
             }
            cout << "After call" << endl;
        }
        

        【讨论】:

        • while(!fut-&gt;_Is_ready() ) 强制行为与提问者不想要的行为相同。主线程基本上被阻塞等待线程完成。