当指定launch :: async时,std :: async不执行 [英] std::async not executing when specifying launch::async
问题描述
也许我错过了在C ++ 11新的 std :: async
的正确用法,但这个语句(在 cppreference.com ):
Maybe I'm missing the correct usage of the new std::async
in C++11, however this statement (over at cppreference.com):
如果设置了async标志(即policy& std :: launch :: async!= 0),则async在单独的执行线程上执行函数f,就好像由std :: thread(f,args ...),除了如果函数f返回一个值或抛出一个异常,它被存储在可通过std :: future访问的共享状态,async返回调用者。
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.
使我认为我的线程应该立即用这个语句开始:
Makes me think that my thread should start immediately with this statement:
std::async(std::launch::async, MyFunctionObject());
无需等待调用 std :: future :: get )
。这似乎不是这样(使用MSVC 13编译)。如果这不是由这个语句本身触发的,如果我不在乎 std :: future
对象的返回值,那么应该如何触发呢?
Without having to wait for calling the std::future::get()
. This seems to not be the case (compiling with MSVC 13). If this is not triggered by this statement itself, how should this get triggered if I don't care about the return value of the std::future
object?
示例:
#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标准
The first thing you have to know is that MSVC std::async
does not conform to the C++11 standard.
在C ++ 11标准下, std :: async
的 std :: future
返回值块直到 std :: async
完成。
Under the C++11 standard, std::async
's std::future
return value blocks until the std::async
completes.
MSVC的实现不会。这使得他们的 std :: async
看起来更友好,但在实践中它是相当棘手。
MSVC's implementation does not. This makes their std::async
seemingly more friendly to use, but in practice it is quite tricky.
但是,因为 std :: async
的行为被描述为 std :: thread
,我们可以看看当你启动 std :: thread
并且无法清理它时会发生。生成的 std :: thread
有效地分离。一旦你退出 main
,C ++标准不指定对 std :: thread $ c $
However, as std::async
's behavior is described in terms of std::thread
, we can look at what happens when you kick off a std::thread
and fail to clean it up. The resulting std::thread
is effectively detached. Once you exit main
, the C++ standard does not specify what happens to such std::thread
s, leaving it up to your particular implementation.
根据一些快速研究,当MSVC Windows程序离开main结束时,线程被终止。
Based off some quick research, when a MSVC windows program goes off the end of main, the threads are terminated.
简而言之,您的程序需要与以某种方式启动的线程重新同步,以便他们可以完成其任务,并防止主程序退出 main
。一个简单的方法是存储从 async
任务返回的 std :: future
In short, your program needs to resynchronize with the threads you launched in some way or another, so that they can complete their tasks, and prevent the main program from exiting main
. An easy way to do that is to store the returned std::future
from your async
task, and wait
on it before main
exits.
如果你有一个符合C ++ 11编译器,您的尝试 async
将不能是异步的,因为它将立即阻止匿名 std :: future
它返回。
If you had a conforming C++11 compiler, your attempted async
would fail to be asynchronous, as it would block immediately upon the destruction of the anonymous std::future
it returned.
最后,注意启动线程
计划在创建后立即运行。它们的运行方式和时间是不可预测的。
Finally, note that launched thread
s and the like may not be scheduled to run immediately after creation. How and when they run is not predictable.
C ++ 11并发原语只是原语。它们中的许多具有古怪的行为,例如 std :: thread
调用 terminate
分离
ed或加入
ed和 async
如果您不存储 future
,则阻止。它们可以用于简单的任务,或用于编写更高级别的库,但它们不是用户友好的。
The C++11 concurrency primitives are merely primitives. Many of them have quirky behavior, like the fact that a std::thread
calls terminate
if it is destroyed without being detach
ed or join
ed, and async
's tendency to block if you don't store the future
. They can be used for simple tasks, or for writing higher level libraries, but they are not user friendly.
这篇关于当指定launch :: async时,std :: async不执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!