Is it safe to create a std::future
from a std::packaged_task
, which executes on a separate thread, but not always retrieve its result?
#include <future>
#include <thread>
class Result {
Result() {}
~Result() {}
};
void foo() {
std::packaged_task<Result()> task(..);
auto future = task.get_future();
std::thread thread(std::move(task), ...);
thread.detach();
if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::ready) {
auto result = future.get(); <--- Task didn't take too long, retrieve future result
...
}
} <--- Task is taking too long, just abort and never call future.get()
It seems to work on Clang / libc++: ~Result()
is called on the returned result by the std::packaged_task
wether or not get()
is eventually called on the std::future
, but since I couldn't find anything in the C++ docs about this usage pattern, I'd like to make sure it's officially supported.
It depends.... on what you consider as safe for your program.
For the context you have shown, it's safe as in:
future
is destroyed before doing a get
on it . If the future was created using std::async
and if you do not call get
on it before it is destroyed, the it would have blocked till the result was available.
these actions will not block for the shared state to become ready, except that 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.
Now, what if the Result
class was holding a non-owning memory (for whatever reason) or some other resource which needs to be manually freed up. In that case, the correctness of your code becomes questionable. A better thing to do would be to dispatch it to some background thread for slow moving tasks.