有没有一种方法可以在C++11中取消/分离未来
Is there a way to cancel/detach a future in C++11?
我有以下代码:
#include <iostream>
#include <future>
#include <chrono>
#include <thread>
using namespace std;
int sleep_10s()
{
this_thread::sleep_for(chrono::seconds(10));
cout << "Sleeping Donen";
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 << "Timeoutn";
}
这应该等待1秒,打印"超时",然后退出。它没有退出,而是额外等待9秒,打印"Sleeping Done"(睡眠完成),然后分段故障。有没有办法取消或分离future,这样我的代码就会在main的末尾退出,而不是等待future完成执行?
C++11标准没有提供直接的方法来取消用std::async
启动的任务。您必须实现自己的取消机制,例如将原子标志变量传递给定期检查的异步任务。
不过,您的代码不应该崩溃。在到达main
结束时,result
中保存的std::future<int>
对象将被销毁,它将等待任务完成,然后丢弃结果,从而清理所有使用的资源。
这里有一个简单的例子,使用原子布尔同时取消一个或多个future。原子bool可以封装在Cancellation类中(取决于口味)。
#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 = ATOMIC_VAR_INIT(false);
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;
}
我知道这是一个老问题,但它仍然是"分离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的末尾,它将在不等待未来结束的情况下退出。
这个宏是不必要的,但如果您要频繁调用它,可以节省键入时间。
// convenience macro to save boilerplate template code
#define START_DETACHED_FUTURE(func)
startDetachedFuture<decltype(func()), decltype(func)>(func)
// works like so:
auto myFuture = START_DETACHED_FUTURE(myFunc);
相关文章:
- 挂起和取消挂起一个文件DLL
- 如何取消对nullptr的屏蔽,返回正确的对象
- C++取消引用指针.为什么会发生变化
- MSVC是否支持C++11样式的属性而不是__declspec
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 如何将模板转换为C++11之前的模板
- 取消引用运算符不能重载
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- c++11评估顺序(未定义的行为)
- 如何在Qt中取消捕获字符串
- C++中的VLA,扩展名为std=C++11
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- "类模板示例<int>;"语句对 C++11 是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 取消一个c++11异步任务
- 有没有一种方法可以在C++11中取消/分离未来
- 如何取消一个特定的线程,而使用c++ 11线程模型或tbb线程类