Dan*_*y A 4 c++ multithreading asynchronous c++11
也许我错过了std::async
C++ 11中新的正确用法,但是这句话(在cppreference.com上):
如果设置了异步标志(即policy&std :: launch :: async!= 0),则async在单独的执行线程上执行函数f,就好像由std :: thread(f,args ...)生成的一样.除了如果函数f返回一个值或抛出异常,它将存储在可通过std :: future访问的共享状态中,async返回给调用者.
让我觉得我的线程应该立即开始这个声明:
std::async(std::launch::async, MyFunctionObject());
Run Code Online (Sandbox Code Playgroud)
无需等待呼叫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;
}
Run Code Online (Sandbox Code Playgroud)
你必须知道的第一件事情是MSVC std::async
不不符合C++ 11个标准.
下的C++ 11标准,std::async
的std::future
返回值的块,直到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
.它们可用于简单任务,也可用于编写更高级别的库,但它们不是用户友好的.