也许我错过了 C++11 中新 std::async
的正确用法,但是这个声明(在 cppreference.com 结束):
If the async flag is set (i.e. policy & std::launch::async != 0), then async executes the function f on a separate thread of execution as if spawned by std::thread(f, args...), except that if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller.
让我觉得我的线程应该立即从这个语句开始:
std::async(std::launch::async, MyFunctionObject());
无需等待调用 std::future::get()
。这似乎不是这种情况(使用 MSVC 13 编译)。如果这不是由该语句本身触发的,如果我不关心 std::future
对象的返回值,应该如何触发它?
示例:
#include <thread>
#include <iostream>
#include <array>
#include <future>
static std::mutex write_mutex;
class Cpp11Threads {
public:
// Function operator for Function-Object
void operator()() {
const int num_threads = 50;
// Static std array
std::array<std::thread*, num_threads> worker_threads;
// Range based
for (std::thread*& thread : worker_threads) {
// Lambda expression
thread = new std::thread(
[] {
static int i = 0;
write_mutex.lock();
std::cout << "Hello, I am happy Std thread #" << i++ << std::endl;
write_mutex.unlock();
});
}
for (std::thread*& thread : worker_threads) {
thread->join();
delete thread;
// nullptr instead of NULL
thread = nullptr;
}
}
};
int main() {
std::async(std::launch::async, Cpp11Threads());
return 0;
}
最佳答案
首先你要知道的是MSVC std::async
不符合 C++11 标准。
在 C++11 标准下,std::async
的 std::future
返回值 block 直到 std::async
完成。
MSVC 的实现没有。这使得他们的 std::async
看似用起来比较友好,实际操作起来还是比较棘手的。
然而,作为std::async
的行为是根据 std::thread
描述的,我们可以看看当你启动 std::thread
时会发生什么并且无法清理它。结果 std::thread
有效分离。一旦你退出 main
,C++ 标准没有指定这样的 std::thread
会发生什么s,将其留给您的特定实现。
根据一些快速研究,当 MSVC windows 程序离开 main 的末尾时,线程将终止。
简而言之,您的程序需要以某种方式与您启动的线程重新同步,以便它们能够完成任务,并防止主程序退出main
.一个简单的方法是存储返回的 std::future
来自你的 async
任务,和 wait
在它之前 main
退出。
如果您有符合标准的 C++11 编译器,您尝试的 async
将无法异步,因为它会在匿名 std::future
销毁后立即阻塞它返回了。
最后,注意启动thread
s 等可能不会安排在创建后立即运行。它们运行的方式和时间无法预测。
C++11 并发原语仅仅是原语。他们中的许多人都有古怪的行为,比如 std::thread
电话 terminate
如果它没有被销毁 detach
编辑或 join
编辑,和async
如果你不存储 future
,它就会阻塞.它们可用于简单的任务,或用于编写更高级别的库,但它们对用户不友好。
关于c++ - std::async 在指定 launch::async 时不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21023477/