我试图异步启动一个函数,但它却同步启动。
#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
答案 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
并不是线程安全的,因此在进行实验时最好使用线程安全记录器。