也许我错过了新std::async在C++11中的正确用法,但是这个语句(在cppreference.com上):
如果设置了异步标志(即policy &std::state::异步= 0),那么异步在单独的执行线程上执行函数f,就像由std::线程(f,args.)生成的那样,除非函数f返回值或抛出异常,它存储在可通过std::期货访问的共享状态中,异步返回给调用方。
使我认为我的线程应该立即以以下语句开头:
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;
}发布于 2014-01-09 15:12:38
您必须知道的第一件事是,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发生了什么,而是留给您特定的实现。
在快速研究的基础上,当MSVC窗口程序从主程序结束时,线程被终止。
简而言之,您的程序需要与您以某种方式启动的线程重新同步,以便它们能够完成任务,并防止主程序退出main。这样做的一个简单方法是从您的std::future任务中存储返回的async,并在main退出之前在其上存储wait。
如果您有一个符合标准的C++11编译器,那么您尝试的async就不会是异步的,因为它会在它返回的匿名std::future被销毁后立即阻塞。
最后,请注意,启动的thread等可能不会在创建后立即运行。他们如何和何时运行是不可预测的。
C++11并发原语仅仅是原语。他们中的许多人都有古怪的行为,比如如果std::thread在没有被detach编辑或join编辑的情况下被破坏,那么它会调用terminate;如果您不存储future,async就会阻止它。它们可以用于简单的任务,也可以用于编写更高级别的库,但它们对用户并不友好。
发布于 2014-01-09 15:00:17
我不太精通C++11,但是每个程序都有一个主线程,它是执行main()函数的线程。当该线程的执行完成时,程序将与其所有线程一起完成。如果希望主线程等待其他线程,则必须使用以下内容
pthread_join
在linux环境中(如果您手动创建线程),或者完全正确
std::未来::get()
在这个特殊的情况下。
退出main会杀死您的线程,在您的情况下可能会阻止您启动线程。
https://stackoverflow.com/questions/21023477
复制相似问题