Reputation: 8569
I'm in a situation where I have a continuous thread working on some input. However, sometimes the work load is too high and the corresponding future will not wait for the result. I need to free some resources in that case, since the computation result then won't be carried on (to be marked as being able to be freed, somewhere else).
Is it possible for the promise to know that the respective future has stopped waiting?
Or could I achieve this effect by other means? (shared_future
, ...?)
As an outline of the concept I have modified the std::promise example, for your easier understanding of what I mean:
using namespace std::chrono_literals;
void accumulate(std::vector<int>::iterator first,
std::vector<int>::iterator last,
std::promise<int> accumulate_promise)
{
int sum = std::accumulate(first, last, 0);
/* Can I possibly know that the corresponding future has stopped
* waiting for this promise, at this very position?
*/
accumulate_promise.set_value(sum);
}
int main()
{
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6 };
std::promise<int> accumulate_promise;
std::future<int> accumulate_future = accumulate_promise.get_future();
std::thread work_thread(accumulate, numbers.begin(), numbers.end(),
std::move(accumulate_promise));
/* Do not wait forever */
accumulate_future.wait_for(1ms);
}
Upvotes: 2
Views: 475
Reputation: 348
Another approach I was thinking about was to pack the std::promise in a std::weak_ptr and lock it in the worker thread when the result is ready, to check if the result is still relevant. But then the caller thread would hold a std::shared_ptr of the std::promise, which - in my opinion - would breaks the 'use only once' concept of the std::promise at least from a software architectural perspective.
Upvotes: 0
Reputation: 62576
Not through the std::promise
. You can include a token alongside the promise to indicate if it should continue.
using namespace std::chrono_literals;
void accumulate(std::vector<int>::iterator first,
std::vector<int>::iterator last,
std::promise<int> accumulate_promise,
std::atomic<bool> & cancellation_token)
{
int sum = std::accumulate(first, last, 0);
if (cancellation_token.load()) return;
accumulate_promise.set_value(sum);
}
int main()
{
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6 };
std::promise<int> accumulate_promise;
std::atomic<bool> token(false);
std::future<int> accumulate_future = accumulate_promise.get_future();
std::thread work_thread(accumulate, numbers.begin(), numbers.end(),
std::move(accumulate_promise), std::ref(token));
if (accumulate_future.wait_for(1ms) != std::future_status::ready)
{
token.store(true);
}
}
Upvotes: 2