I am using a combination of std::async
and std::future
from C++ 11
. I am using to enforce a time_out on a certain activity that I do in my code which might take time as I try connecting to server.
Following is how the code is:
#include <future>
#include <chrono>
std::size_t PotentiallyLongRunningActivity() {
using namespace std::chrono_literals;
std::this_thread::sleep_for(10000s);
return 10;
}
bool DoActivity() {
bool activity_done = false;
auto my_future_result(std::async(std::launch::async, []() {
return PotentiallyLongRunningActivity(); //returns size_t
}));
std::future_status my_future_status = my_future_result.wait_for(std::chrono::milliseconds(800));
if (my_future_status == std::future_status::timeout) {
activity_done = false;
}
else if (my_future_status == std::future_status::ready) {
if (my_future_result.valid() && my_future_result.get() > 0) {
activity_done = true;
}
}
return activity_done;
//my_future_result hangs while exiting this method !!!
}
int main(int argc, char *argv[])
{
DoActivity();
return 0;
}
Things work fine in most of the cases. The future times out & is reported ready in many cases. But, Strange behavior I am observing is that in some cases the UI hangs because my_future_result
when going out of scope hangs. I confirmed this by repeating the call to my_future_result.get()
which never returns if called just before exiting the method.
How can I get around this ? Is there some way I cancel or delete or terminate the std::future
?
You are exiting your function before the std::async
task has completed. Under certain circumstances, the destructor for a std::future
will block until the task has completed.
http://en.cppreference.com/w/cpp/thread/future/wait_for
Here in the documentation for wait_for
the example shows multiple calls to wait_for
after timeouts, showing that the act of timing out does not cancel the std::async
task.
There is no built-in support (that I could discover) that allows for threads to be killed externally. This makes sense as there isn't a way to properly clean up the state of system resources in use by the thread if it is terminated in this way.
Instead, it is better to place the timeout logic in the thread itself, so that it can terminate itself and clean up properly.