std::async not executing when specifying launch::async
Maybe I'm missing the correct usage of the new std::async
in C++11, however this statement (over at cppreference.com):
If the async flag is set (ie 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());
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?
Example:
#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;
}
The first thing you have to know is that MSVC std::async
does not conform to the C++11 standard.
Under the C++11 standard, std::async
's std::future
return value blocks until the std::async
completes.
MSVC's implementation does not. This makes their std::async
seemingly more friendly to use, but in practice it is quite tricky.
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.
Based off some quick research, when a MSVC windows program goes off the end of main, the threads are terminated.
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.
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.
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.
I'm not proficient with C++11 but AFAIK each program has a main thread and it is the thread in which your main() function executes. When the execution of that thread finishes, the program finishes along with all its threads. If you want your main thread to wait for other threads, use must use something like
pthread_join
in a linux environment (if you created your thread manually), or exactly
std::future::get()
in this specific case.
Exiting main will kill your threads and in your case probably prevent you from launching the thread at all
链接地址: http://www.djcxy.com/p/5208.html上一篇: 使用两个线程运行并中断一个无限循环