取消c ++ 11异步任务

时间:2012-12-03 06:21:22

标签: c++ asynchronous c++11

如何停止/取消使用std::async和策略std::launch::async创建的异步任务?换句话说,我已经使用future对象启动了在另一个线程上运行的任务。有没有办法取消或停止正在运行的任务?

3 个答案:

答案 0 :(得分:23)

简而言之。

更长的解释:没有安全的方法来取消标准C ++中的任何线程。这将需要线程取消。在C ++ 11标准化过程中已经多次讨论过这个特性,普遍的共识是没有安全的方法可以做到这一点。据我所知,有三种主要考虑的方法在C ++中进行线程消除。

  1. 中止线程。这就像紧急停止。不幸的是,它会导致没有堆栈展开或析构函数被调用。该线程可能处于任何状态,因此可能持有互斥体,堆积分配的数据将被泄露等。这显然永远不会被考虑很长时间,因为它会使整个程序未定义。如果你想自己做,但只需使用native_handle即可。然而,它将是不可携带的。

  2. 强制取消/中断点。当请求线程取消时,它在内部设置一些变量,以便下次调用任何预定义的一组中断点(例如睡眠,等待等)时,它会抛出一些异常。这将导致堆栈展开并且可以完成清理。不幸的是,这种类型的系统很难使任何代码异常安全,因为大多数多线程代码可能突然抛出。这是boost.thread使用的模型。它使用disable_interruption来解决一些问题,但除了最简单的情况之外,它仍然非常难以做到。 Boost.thread使用这个模型,但它一直被认为是有风险的,可以理解的是,标准与其他标准一起被接受。

  3. 自愿取消/中断点。最终这归结为在你想要的时候自己检查某些条件,并且如果合适的话以自己的方式退出线程。我含糊地回忆起一些关于增加一些图书馆功能的讨论,但它从来没有达成一致意见。

  4. 我只使用3的变体。例如,如果你使用lambdas,那么引用一个原子“取消”变量就很容易了,你可以不时检查它。

答案 1 :(得分:3)

在C ++ 11中(我认为)没有标准的取消线程的方法。如果你得到std :: thread :: native_handle(),你可以用它做一些事情,但那不可移植。

答案 2 :(得分:-1)

也许你可以通过检查某些条件来这样做:

class Timer{
public:
    Timer():timer_destory(false){}
    ~Timer(){
        timer_destory=true;
        for(auto result:async_result){
            result.get();
        }
    }
    int register_event(){
        async_result.push_back(
            std::async(std::launch::async,[](std::atomic<bool>& timer_destory){
                while(!timer_destory){
                //do something
                }
            },std::ref(timer_destory))
            );
    }
private:
    std::vector<std::future<int>> async_result;
    std::atomic<bool> timer_destory;
}