std::async and std::future behaviour

std::async and std::future behaviour

本文关键字:std behaviour future async and      更新时间:2023-10-16

我试图理解异步行为并编写了一些愚蠢的测试程序。

int f(int i)
    {
        std::cout << i << ": hello" << std::endl;
        int j = 0;
        while (j < 10000) //just add some delay
        {
            j++;
        }
        return j;
    }
int main()
{
    for (int i = 0; i < 10000; i++)
    {
        std::async(std::launch::async, f, i);
    }
    std::cout << "in main" << std::endl;
}

使用上面的代码,输出似乎是完全同步的。所有 10000 个线程似乎都按顺序执行。主线程块。

0: hello
1: hello
2: hello
.......
10000: hello
in main

但是,当返回的未来存储在向量中时,输出将被全部破坏,并且主输出将退出,而无需等待生成的线程。线程在这里分离了吗?

int main()
{
    std::vector<std::future<int>> v;
    for (int i = 0; i < 10000; i++)
    {
        v.push_back(std::move(std::async(std::launch::async, f, i)));
    }
    std::cout << "in main" << std::endl;
}

输出:

2: hello3: hello
46: hello
: hello5: hello
9: hello
10: hello
11: hello

最后,尝试在返回的未来使用 get() 仍然给出类似的损坏输出:

int main()
{
    std::vector<std::future<int>> v;
    for (int i = 0; i < 10000; i++)
    {
        v.push_back(std::move(std::async(std::launch::async, f, i)));
    }
    for (int i = 0; i < 10000; i++)
    {
        std::cout << v[i].get();    
    }
    std::cout << "in main" << std::endl;
}

输出:

3: hello
4: hello
1: hello
5: hello
0: hello
2: hello

我会认为在第一种情况下,主节点将退出而不等待在后台运行的线程。至少在第 3 种情况下,main 将在 future.get() 上阻塞。

引擎盖下到底发生了什么?

异步返回的期货在其 dtor 中隐式执行.wait(),但是:这种行为可以move

这解释了您的所有症状。