std :: launch :: async像同步过程一样阻塞

我正在运行Visual Studio 2012并试图了解std :: async如何工作。 我创建了一个非常简单的C ++控制台应用程序:

#include "stdafx.h"
#include <future>
#include <iostream>

void foo() {
    std::cout << "foo() thread sleep" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "foo() thread awake" << std::endl;
}

int main()
{
    std::future<void> res = std::async(std::launch::async, foo);
    res.get();
    std::cout << "MAIN THREAD" << std::endl;

    system("pause");

    return 0;
}

我最初的期望是 “foo()线程清醒” 之前看到“MAIN THREAD”打印输出,因为两个线程异步运行,foo()由于其睡眠行为而落后。 但是,这不是实际发生的情况。 调用res.get()会阻塞,直到foo()唤醒,然后才会进入“MAIN THREAD”打印输出。 这是一个同步行为的指示,所以我想知道如果我可能错过了一些东西,或者没有完全掌握实现。 我已经浏览了很多关于这个问题的帖子,但是仍然没有任何意义。 任何帮助,将不胜感激!


 res.get();

直到异步结束。

http://en.cppreference.com/w/cpp/thread/future/get

不管你如何告诉它运行, get直到把它完成不能给你结果。


那么,这是怎么std::future::get作品 - 它阻止,直到future有一些结果或例外提供。

这并不意味着async同步工作,它异步工作的,只是因为你阻塞了等待结果的线程。

这个想法是要异步启动一些任务,同时做一些事情,只有当你需要结果时才打电话get你,正如你可能知道的那样,这不是最可扩展的事情。

如果您使用Visual Studio 2015,则可以访问std::futureconcurrency::task (Microsoft PPL库)的await关键字以及您自己的兼容定义类型。 这实现了非阻塞行为。

#include "stdafx.h"
#include <future>
#include <iostream>

void foo() {
    std::cout << "foo() thread sleep" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "foo() thread awake" << std::endl;
}

std::future<void> entry(){
     await std::async(std::launch::async, foo);
     std::cout << "foo has finished, back in entry()n";
}

int main()
{
    std::cout << "MAIN THREAD" << std::endl;
    entry();
     std::cout << "BACK INMAIN THREAD" << std::endl;
    system("pause");

    return 0;
} //make sure to compile with /await flag

问题是res.get()必须等待其线程完成才能获得结果(如果有的话)。 要查看运动中的并发性,您需要将get()移至想要同时运行的其他代码之后。

这个例子可能会使它更清晰一些:

#include <ctime>
#include <cstdlib>
#include <future>
#include <iostream>

void foo(int id) {
    std::cout << "foo(" << id << ") thread sleep" << std::endl;
    // random sleep
    std::this_thread::sleep_for(std::chrono::seconds(std::rand() % 10));
    std::cout << "foo(" << id << ") thread awake" << std::endl;
}

int main()
{
    std::srand(std::time(0));

    std::future<void> res1 = std::async(std::launch::async, foo, 1);
    std::future<void> res2 = std::async(std::launch::async, foo, 2);
    std::future<void> res3 = std::async(std::launch::async, foo, 3);

    std::cout << "MAIN THREAD SLEEPING" << std::endl;

    std::this_thread::sleep_for(std::chrono::seconds(20));

    std::cout << "MAIN THREAD AWAKE" << std::endl;

    // now wait for all the threads to end
    res1.get();
    res2.get();
    res3.get();

    system("pause");

    return 0;
}
链接地址: http://www.djcxy.com/p/30735.html

上一篇: std::launch::async is blocking like a sync process

下一篇: std::async with temporary future returned