我有以下代码:
#include <iostream>
#include <future>
#include <chrono>
#include <thread>
using namespace std;
int sleep_10s()
{
this_thread::sleep_for(chrono::seconds(10));
cout << "Sleeping Done\n";
return 3;
}
int main()
{
auto result=async(launch::async, sleep_10s);
auto status=result.wait_for(chrono::seconds(1));
if (status==future_status::ready)
cout << "Success" << result.get() << "\n";
else
cout << "Timeout\n";
}
这应该等待1秒钟,打印“超时”,然后退出。它不再退出,而是再等9秒,打印“Sleep Done”,然后是段错误。有没有办法取消或分离未来所以我的代码将在main结束时退出而不是等待将来完成执行?
答案 0 :(得分:23)
C ++ 11标准没有提供取消以std::async
开头的任务的直接方法。您必须实现自己的取消机制,例如将原子标志变量传递给定期检查的异步任务。
您的代码不应该崩溃。到达main
的末尾时,std::future<int>
中保存的result
对象将被销毁,等待任务完成,然后丢弃结果,清理所有使用的资源。 / p>
答案 1 :(得分:14)
这是一个使用原子bool同时取消一个或多个future的简单示例。原子布尔可以包含在取消类中(取决于品味)。
#include <chrono>
#include <future>
#include <iostream>
using namespace std;
int long_running_task(int target, const std::atomic_bool& cancelled)
{
// simulate a long running task for target*100ms,
// the task should check for cancelled often enough!
while(target-- && !cancelled)
this_thread::sleep_for(chrono::milliseconds(100));
// return results to the future or raise an error
// in case of cancellation
return cancelled ? 1 : 0;
}
int main()
{
std::atomic_bool cancellation_token;
auto task_10_seconds= async(launch::async,
long_running_task,
100,
std::ref(cancellation_token));
auto task_500_milliseconds = async(launch::async,
long_running_task,
5,
std::ref(cancellation_token));
// do something else (should allow short task
// to finish while the long task will be cancelled)
this_thread::sleep_for(chrono::seconds(1));
// cancel
cancellation_token = true;
// wait for cancellation/results
cout << task_10_seconds.get() << " "
<< task_500_milliseconds.get() << endl;
}
答案 2 :(得分:3)
我知道这是一个老问题,但是在搜索时,它仍然是“ detach std :: future”的最高结果。我想出了一种基于模板的简单方法来处理此问题:
template <typename RESULT_TYPE, typename FUNCTION_TYPE>
std::future<RESULT_TYPE> startDetachedFuture(FUNCTION_TYPE func) {
std::promise<RESULT_TYPE> pro;
std::future<RESULT_TYPE> fut = pro.get_future();
std::thread([&func](std::promise<RESULT_TYPE> p){p.set_value(func());},
std::move(pro)).detach();
return fut;
}
您可以像这样使用它:
int main(int argc, char ** argv) {
auto returner = []{fprintf(stderr, "I LIVE!\n"); sleep(10); return 123;};
std::future<int> myFuture = startDetachedFuture<int, decltype(returner)>(returner);
sleep(1);
}
输出:
$ ./a.out
I LIVE!
$
如果myFuture超出范围并被破坏,则该线程将继续执行其所做的任何操作而不会引起问题,因为它拥有std :: promise及其共享状态。适用于您有时只希望忽略计算结果而继续前进的场合(我的用例)。
OP的问题:如果您到达main的结尾,它将退出而无需等待将来的完成。