简体   繁体   English

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

[英]std::launch::async is blocking like a sync process

I am running Visual Studio 2012 and attempting to learn how std::async works. 我正在运行Visual Studio 2012并尝试了解std :: async的工作原理。 I have created a very simple C++ console application: 我创建了一个非常简单的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;
}

My initial expectation was to see "MAIN THREAD" printout appearing before "foo() thread awake" since the two threads are running asynchronously, with the foo() trailing behind due to its sleeping behavior. 我最初的期望是看到“MAIN THREAD”打印输出出现 “foo()线程唤醒”之前,因为两个线程是异步运行的,foo()由于其休眠行为而落后。 However, that is not what is actually happening. 然而,这不是实际发生的事情。 The call to res.get() blocks until foo() wakes up, and only then does it get to the "MAIN THREAD" printout. 对res.get()的调用会阻塞,直到foo()唤醒,然后才会进入“MAIN THREAD”打印输出。 This is indicative of a synchronous behavior, so I am wondering what if perhaps I am either missing something, or not fully grasping the implementation. 这表示同步行为,所以我想知道如果我或许要么缺少某些东西,要么不完全掌握实现。 I have looked through numerous posts on this matter, but still cannot make any sense of it. 我已经看了很多关于此事的帖子,但仍然无法理解它。 Any help would be appreciated! 任何帮助,将不胜感激!

 res.get();

blocks until the async is done. 阻止,直到异步完成。

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

Regardless of how you tell it to run, get can't give you the results until it's done. 无论你如何告诉它运行,在完成之前, get都无法给你结果。

Well, this is how std::future::get works - it blocks until future has some result or exception to provide. 好吧,这就是std::future::get工作方式 - 它会阻塞,直到future有一些结果或异常提供。

that doesn't mean that async works synchronously, it is working asynchronously, it's only because you block the thread which waits on the result. 这并不意味着async同步工作,它异步工作的,只是因为你阻塞了等待结果的线程。

the idea was to to launch some task asynchronously, do something meanwhile and only call get when you need the result, as you might figured out, it is not the most scale-able thing.. 我的想法是异步启动一些任务,同时做一些事情,只在你需要结果时调用get ,正如你可能想到的那样,它不是最具扩展性的东西。

if you use Visual Studio 2015, you can access the await keyword both for std::future and concurrency::task (Microsoft PPL library) , and for your own compatible defined types. 如果您使用Visual Studio 2015,则可以访问std::futureconcurrency::task (Microsoft PPL库)以及您自己的兼容定义类型的await关键字。 this achieves non-blocking behavior. 这实现了非阻塞行为。

#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

The problem is that res.get() has to wait for its thread to finish before getting its result (if any). 问题是res.get()必须等待其线程完成才能获得结果(如果有的话)。 To see the concurrency in motion you need to move the get() to after the other code that you want to run at the same time. 要查看运动中的并发性,您需要将get()移动到要同时运行的其他代码之后。

This example may make it a little clearer: 这个例子可能会让它更清晰一些:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM