C ++异步功能未异步启动

时间:2018-09-19 15:51:49

标签: c++11 asynchronous promise

我试图异步启动一个函数,但它却同步启动。

#include <thread>
#include <future>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

std::future<int> setPromise()
{
    auto promise = std::make_shared<std::promise<int>>();
    auto future = promise->get_future();
    auto asyncFn = [&]() {
      cout << "Async started ...\n";
      for(int i=0; i<100000; i++)
        for(int j=0; j<10000; j++) {}
      promise->set_value(400);
      fprintf(stderr, "Async ended ...\n");
    };
    std::async(std::launch::async, asyncFn);
    return future;
}

int main()
{
   std::future<int> result = setPromise();
   cout << "Asynchronously launched \n";
   int ret = result.get();
   cout << ret << endl;

   return 0;
}

使用以下命令进行编译

g++ -std=c++11 -pthread promise.cpp -o promise 

我期望lambda函数被异步调用,并且当循环在异步线程中运行时,我期望来自主线程的日志。但是我看到该函数永远不会异步启动,并且lambda总是会完成,只有这样我们才能在main中执行下一条语句

我期望

Async started ...
Asynchronously launched
Async ended ...

我得到的是

Async started ...
Async ended ...
Asynchronously launched

2 个答案:

答案 0 :(得分:2)

通过在行下方调用

std::async(std::launch::async, asyncFn);

被创建为临时future对象,并且其析构函数仅在由async开始的任务完成时结束。因此,在setPromise函数范围的末尾,它的执行被阻止,直到作业-asyncFn结束为止。

您可以了解有关行为未来破坏者here的信息,以及将来的共享状态未准备好时会发生什么。

答案 1 :(得分:0)

它可能正在异步运行,只是很快完成。

为确保确定,您需要释放日志记录竞争条件。

类似这样的东西(只是想法):

std::future<int> setPromise()
{
    std::atomic_flag canGo = ATOMIC_FLAG_INIT;

    auto asyncFn = [&] {
        while (!canGo);
        log("Async started ..."); // also use thread-safe logging
        ...
    }

    std::async(std::launch::async, asyncFn);
    log("letting it go...");
    canGo.test_and_set();

    ...
}

还请注意,iostream并不是线程安全的,因此在进行实验时最好使用线程安全记录器。