I create a std::packaged_task
, push it to a std::list
and return its std::future
to users, like this:
future_t emplace(...)
{
//...
auto task = std::make_shared<std::packaged_task<return_t()>>(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));
tasks.emplace_back(task);
std::future<return_t> result = task->get_future();
//...
return result;
}
In another thread, we may clear the tasks list at anytime:
// another thread
std::list<task_t> temp_{};
tasks.swap(temp_);
But users may call std::future still:
auto result = emplace(...);
// do something and the tasks list has been clear in anthor thread
auto ret = result.get();
Get a exception error as std::promise has been destroyed:
C++ exception with description "std::future_error: Broken promise" thrown in the test body.
I can use a exception expression to avoid the program broken:
try
{
auto ret = result.get();
}
catch (...)
{
}
Can I avoid std::future_error
without exception expression?
My question is: Is there any other method to detect if the std::promise exist?
I'm afraid there is no direct way to detect if the promise still exists. If you must do that, you may have to do some additional work to keep the state of the
task
(or the correspondingfuture
), which is more complicated than the current solution. Allfuture
s are by default invalid. Whenever you execute the task, you mark thefuture
is valid. Whenever you're to get a result through afuture
, check if it's valid.Notice: you have to handle the synchronization of this state since this state is shared between different threads. That sounds wired, right? You're going to share another data outside the pairwise promise and future. I don't recommend and don't think it's necessary to do so.
When you're using
std::promise
andstd::future
, all exceptions should be handled in thestd::future::get
.