It seems that unless you call std::async a std::future will never be set to any other state than future_status::deferred unless you call get or wait on the future. wait_for & wait_until will continue to not block and return future_status::deferred even if the task has already run and stored the result.
Here's an example:
#include <future>
void main()
{
auto func = []() { return 5; };
auto asyncFuture = std::async(std::launch::async, func);
auto status = asyncFuture.wait_for(std::chrono::seconds(0)); // timeout (1)
auto deferredFuture = std::async(std::launch::deferred, func);
status = deferredFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
std::packaged_task<int()> task(func);
auto packagedTaskFuture = task.get_future();
status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
task();
status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
packagedTaskFuture.wait();
status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // ready (0)
}
I don't have the current C++11 standard, but the draft standard in 30.6.9 says that when a packaged_task is run it should store the result in the future's shared state. It's not very clear whether that includes setting the expected wait_until/wait_for behavior or not.
There were previously issues with VS11 behavior in this area with respect to async calls: http://social.msdn.microsoft.com/Forums/hu/parallelcppnative/thread/4394f2c1-0404-40df-869b-f4fc36fc035c
Additionally it seems like other compilers have problems in this area: C++ 11 future_status::deferred not working
Anyone that may know the standard better: Is this expected behavior or is there an issue with the implemenation in VS11?
Updates: I somehow missed the report for this: http://connect.microsoft.com/VisualStudio/feedback/details/761829/c-11-unexpected-behavior-for-std-future-wait-for-and-std-packaged-task
This is an issue with VS2012. It's not the only issue either --- their implementation of the C++11 thread library has several bugs. I wrote about a few on my blog.
Related
I'm trying to learn async programming in C++. In Python, we have await, with which we can resume a function from that point, but in C++ future waits for the results and halts the next line of code. What if we don't want to get the result, but instead continue to the next line of code? How can I do this?
You can use std::future::wait_for to check if the task has completed execution, e.g.:
if (future.wait_for(100ms) == std::future_status::ready) {
// Result is ready.
} else {
// Do something else.
}
The Concurrency TS includes std::future::is_ready (may be included in C++20), which is non blocking. If it gets included in the standard, usage will be something like:
auto f = std::async(std::launch::async, my_func);
while (!f.is_ready()) {
/* Do other stuff. */
}
auto result = f.get();
/* Do stuff with result. */
Alternatively, the Concurrency TS also includes std::future::then, which I interpret can be used e.g. as:
auto f = std::async(std::launch::async, my_func)
.then([] (auto fut) {
auto result = fut.get();
/* Do stuff when result is ready. */
});
/* Do other stuff before result is ready. */
Also see: How to check if a std::thread is still running?
future waits for the results and halts the next line of code
This is only true when you invoke .get() or when the future is being destroyed. You can run multiple tasks in parallel with std::future:
std::future<int> f = std::async(std::launch::async, foo);
auto res0 = bar();
auto res1 = f.get();
In the example above, bar and foo will run in parallel.
If you want to attach asynchronous continuations to an existing future, currently you cannot do that with std::future.
boost::future supports non-blocking .then(...), .when_all(...), and .when_any(...) continuations. These are proposed for standardization in "Extensions for concurrency".
There's also a "Coroutines" TS that aims to introduce resumable functions and co_await/co_yield.
Unsurprisingly, boost also provides a coroutine library that can be used today to implement resumable functions.
While working with the threaded model of C++11, I noticed that
std::packaged_task<int(int,int)> task([](int a, int b) { return a + b; });
auto f = task.get_future();
task(2,3);
std::cout << f.get() << '\n';
and
auto f = std::async(std::launch::async,
[](int a, int b) { return a + b; }, 2, 3);
std::cout << f.get() << '\n';
seem to do exactly the same thing. I understand that there could be a major difference if I ran std::async with std::launch::deferred, but is there one in this case?
What is the difference between these two approaches, and more importantly, in what use cases should I use one over the other?
Actually the example you just gave shows the differences if you use a rather long function, such as
//! sleeps for one second and returns 1
auto sleep = [](){
std::this_thread::sleep_for(std::chrono::seconds(1));
return 1;
};
Packaged task
A packaged_task won't start on it's own, you have to invoke it:
std::packaged_task<int()> task(sleep);
auto f = task.get_future();
task(); // invoke the function
// You have to wait until task returns. Since task calls sleep
// you will have to wait at least 1 second.
std::cout << "You can see this after 1 second\n";
// However, f.get() will be available, since task has already finished.
std::cout << f.get() << std::endl;
std::async
On the other hand, std::async with launch::async will try to run the task in a different thread:
auto f = std::async(std::launch::async, sleep);
std::cout << "You can see this immediately!\n";
// However, the value of the future will be available after sleep has finished
// so f.get() can block up to 1 second.
std::cout << f.get() << "This will be shown after a second!\n";
Drawback
But before you try to use async for everything, keep in mind that the returned future has a special shared state, which demands that future::~future blocks:
std::async(do_work1); // ~future blocks
std::async(do_work2); // ~future blocks
/* output: (assuming that do_work* log their progress)
do_work1() started;
do_work1() stopped;
do_work2() started;
do_work2() stopped;
*/
So if you want real asynchronous you need to keep the returned future, or if you don't care for the result if the circumstances change:
{
auto pizza = std::async(get_pizza);
/* ... */
if(need_to_go)
return; // ~future will block
else
eat(pizza.get());
}
For more information on this, see Herb Sutter's article async and ~future, which describes the problem, and Scott Meyer's std::futures from std::async aren't special, which describes the insights. Also do note that this behavior was specified in C++14 and up, but also commonly implemented in C++11.
Further differences
By using std::async you cannot run your task on a specific thread anymore, where std::packaged_task can be moved to other threads.
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::thread myThread(std::move(task),2,3);
std::cout << f.get() << "\n";
Also, a packaged_task needs to be invoked before you call f.get(), otherwise you program will freeze as the future will never become ready:
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::cout << f.get() << "\n"; // oops!
task(2,3);
TL;DR
Use std::async if you want some things done and don't really care when they're done, and std::packaged_task if you want to wrap up things in order to move them to other threads or call them later. Or, to quote Christian:
In the end a std::packaged_task is just a lower level feature for implementing std::async (which is why it can do more than std::async if used together with other lower level stuff, like std::thread). Simply spoken a std::packaged_task is a std::function linked to a std::future and std::async wraps and calls a std::packaged_task (possibly in a different thread).
TL;DR
std::packaged_task allows us to get the std::future "bounded" to some callable, and then control when and where this callable will be executed without the need of that future object.
std::async enables the first, but not the second. Namely, it allows us to get the future for some callable, but then, we have no control of its execution without that future object.
Practical example
Here is a practical example of a problem that can be solved with std::packaged_task but not with std::async.
Consider you want to implement a thread pool. It consists of a fixed number of worker threads and a shared queue. But shared queue of what? std::packaged_task is quite suitable here.
template <typename T>
class ThreadPool {
public:
using task_type = std::packaged_task<T()>;
std::future<T> enqueue(task_type task) {
// could be passed by reference as well...
// ...or implemented with perfect forwarding
std::future<T> res = task.get_future();
{ std::lock_guard<std::mutex> lock(mutex_);
tasks_.push(std::move(task));
}
cv_.notify_one();
return res;
}
void worker() {
while (true) { // supposed to be run forever for simplicity
task_type task;
{ std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this]{ return !this->tasks_.empty(); });
task = std::move(tasks_.top());
tasks_.pop();
}
task();
}
}
... // constructors, destructor,...
private:
std::vector<std::thread> workers_;
std::queue<task_type> tasks_;
std::mutex mutex_;
std::condition_variable cv_;
};
Such functionality cannot be implemented with std::async. We need to return an std::future from enqueue(). If we called std::async there (even with deferred policy) and return std::future, then we would have no option how to execute the callable in worker(). Note that you cannot create multiple futures for the same shared state (futures are non-copyable).
Packaged Task vs async
p> Packaged task holds a task [function or function object] and future/promise pair. When the task executes a return statement, it causes set_value(..) on the packaged_task's promise.
a> Given Future, promise and package task we can create simple tasks without worrying too much about threads [thread is just something we give to run a task].
However we need to consider how many threads to use or whether a task is best run on the current thread or on another etc.Such descisions can be handled by a thread launcher called async(), that decides whether to create a new a thread or recycle an old one or simply run the task on the current thread. It returns a future .
"The class template std::packaged_task wraps any callable target
(function, lambda expression, bind expression, or another function
object) so that it can be invoked asynchronously. Its return value or
exception thrown is stored in a shared state which can be accessed
through std::future objects."
"The template function async runs the function f asynchronously
(potentially in a separate thread) and returns a std::future that will
eventually hold the result of that function call."
I'm learning about mutexes in C++ and have a problem with the following code (taken from N. Josuttis' "The C++ Standard Library").
I don't understand why it blocks / throws unless I add this_thread::sleep_for in the main thread (then it doesn't block and all three calls are carried out).
The compiler is cl.exe used from the command line.
#include <future>
#include <mutex>
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
std::mutex printMutex;
void print(const std::string& s)
{
std::lock_guard<std::mutex> lg(printMutex);
for (char c : s)
{
std::cout.put(c);
}
std::cout << std::endl;
}
int main()
{
auto f1 = std::async(std::launch::async, print, "Hello from thread 1");
auto f2 = std::async(std::launch::async, print, "Hello from thread 2");
// std::this_thread::sleep_for(std::chrono::seconds(1));
print(std::string("Hello from main"));
}
I think what you are seeing is an issue with the conformance of the MSVC implementation of async (in combination with future). I believe it is not conformant. I am able to reproduce it with VS2013, but unable to reproduce the issue with gcc.
The crash is because the main thread exits (and starts to clean up) before the other two threads complete.
Hence a simple delay (the sleep_for) or .get() or .wait() on the two futures should fix it for you. So the modified main could look like;
int main()
{
auto f1 = std::async(std::launch::async, print, "Hello from thread 1");
auto f2 = std::async(std::launch::async, print, "Hello from thread 2");
print(std::string("Hello from main"));
f1.get();
f2.get();
}
Favour the explicit wait or get over the timed "sleep".
Notes on the conformance
There was a proposal from Herb Sutter to change the wait or block on the shared state of the future returned from async. This may be the reason for the behaviour in MSVC, it could be seen as having implemented the proposal. I'm not sure what the final result was of the proposal was or its integration (or part thereof) into C++14. At least w.r.t. the blocking of the future returned from async it looks like the MSVC behaviour did not make it into the specification.
It is interesting to note that the wording in §30.6.8/5 changed;
From C++11
a call to a waiting function on an asynchronous return object that shares the shared state created
by this async call shall block until the associated thread has completed, as if joined
To C++14
a call to a waiting function on an asynchronous return object that shares the shared state created
by this async call shall block until the associated thread has completed, as if joined, or else time
out
I'm not sure how the "time out" would be specified, I would imagine it is implementation defined.
std::async returns a future. Its destructor blocks if get or wait has not been called:
it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.
See std::futures from std::async aren't special! for a detailed treatment of the subject.
Add these 2 lines at the end of main:
f1.wait();
f2.wait();
This will make sure the threads finish before main exists.
To my surprise, a C++11 std::thread object that has finished executing, but has not yet been joined is still considered an active thread of execution. This is illustrated in the following code example (built on Xubuntu 13.03 with g++ 4.7.3). Does anyone know if the C++11 standard provides a means to detect if a std::thread object is still actively running code?
#include <thread>
#include <chrono>
#include <iostream>
#include <pthread.h>
#include <functional>
int main() {
auto lambdaThread = std::thread([](){std::cout<<"Excuting lambda thread"<<std::endl;});
std::this_thread::sleep_for(std::chrono::milliseconds(250));
if(lambdaThread.joinable()) {
std::cout<<"Lambda thread has exited but is still joinable"<<std::endl;
lambdaThread.join();
}
return 0;
}
No, I don't think that this is possible. I would also try to think about your design and if such a check is really necessary, maybe you are looking for something like the interruptible threads from boost.
However, you can use std::async - which I would do anyway - and then rely on the features std::future provides you.
Namely, you can call std::future::wait_for with something like std::chrono::seconds(0). This gives you a zero-cost check and enables you to compare the std::future_status returned by wait_for.
auto f = std::async(foo);
...
auto status = f.wait_for(std::chrono::seconds(0));
if(status == std::future_status::timeout) {
// still computing
}
else if(status == std::future_status::ready) {
// finished computing
}
else {
// There is still std::future_status::defered
}
for what definition of "actively running code"? not that I know of, I'm not sure what state the thread is left in after it becomes joinable, in most cases I can think of you'd actually want fine grain control, like a flag set by the code running in that thread, anyway
for a platform specific solution, you could use GetThreadTimes
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++: Simple return value from std::thread?
Is there anyway to get the return code from a std::thread? I have a function which returns a integer, and I want to be able to get the return code from the function when the thread is done executing.
No, that's not what std::thread is for.
Instead, use async to get a future:
#include <future>
int myfun(double, char, bool);
auto f = std::async(myfun, arg1, arg2, arg3); // f is a std::future<int>
// ...
int res = f.get();
You can use the wait_for member function of f (with zero timeout) to see if the result is ready.
As others have suggested, the facilities in <future> can be used for this. However I object to the answer
No, you can't do this with std::thread
Here is one way to do what you want with std::thread. It is by no means the only way:
#include <thread>
#include <iostream>
int func(int x)
{
return x+1;
}
int main()
{
int i;
std::thread t([&] {i = func(2);});
t.join();
std::cout << i << '\n';
}
This will portably output:
3
Kerrek SB is correct with his answer, but I suggested to add another example (which he suggested should be an answer, so here it is).
I discovered recently that at least in VC11, std::async will not release all the resources of the thread until the end of the application, making possible to get memory leak false positive (if you are monitoring them using, for example Visual Leak Detector).
Here I mean that in most basic applications it is not worth looking at the rest of this answer, but if like me you need to check memory leaks and can't afford to let false positive, like static data not released at the end of the main function. If it's your case, then this might help.
std::async is not guaranteed to run in a separate thread by default, it is only if you use std::launch::async as first parameter. Otherwise the implementation decide what to do, and that's why VC11 implementation will use the new Microsoft Concurrency Runtime task manager to manage the provided function as a task pushed in a task pool, which mean threads are maintained and managed in a transparent way. There are ways to explicitely terminate the task manager but that's too platform specific, making async a poor choice when you want exactly 1) be sure to launch a thread and 2) get a result later and 3) be sure the thread is fully released when you get the result.
The alternative that does exactly that is to use std::packaged_task and std::thread in combination with std::future. The way it is done is almost similar to using std::async, just a bit more verbose (which mean you can generalize it in a custom template function if you want).
#include <packaged_task>
#include <thread>
int myfun(double, char, bool);
std::packaged_task<int(double, char, bool)> task(myfun, arg1, arg2, arg3);
auto f = task.get_future(); // f is a std::future<int>
First we create a task, basically an object containing both the function and the std::promise that will be associated with the future. std::packaged_task works mostly like an augmented version of std::function:
Now we need to execute the thread explicitly:
std::thread thread(std::move(task));
thread.detach();
The move is necessary because std::packaged_task is not copyable. Detaching the thread is only necessary if you only want to synchronize using the future – otherwise you will need to join the thread explicitly. If you don't, when thread's destructor is called, it will just call std::terminate().
// ...
int res = f.get(); // Synchronization and retrieval.
Here's an example using packaged_task:
#include <future>
#include <iostream>
void task_waiter(std::future<int>&& f) {
std::future<int> ft = std::move(f);
int result = ft.get();
std::cout << result << '\n';
}
int the_task() {
return 17;
}
int main() {
std::packaged_task<int()> task(the_task);
std::thread thr(task_waiter, task.get_future());
task();
thr.join();
return 0;
}