std::async和std::future的行为

4

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

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

最后,尝试对返回的future使用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

我认为在第一种情况下,主线程将退出而不等待在后台运行的线程。至少在第三种情况下,主线程将在future.get()上阻塞。
底层到底发生了什么?

主函数在异步完成之前并未退出,实际上。 ;) - Yakk - Adam Nevraumont
1个回答

6
异步返回的未来对象在其析构函数中隐式执行了.wait(),但是:这种行为可以被move。这就解释了你所有的症状。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接