c++中止运行中的函数

我现在有一个函数需要执行,但是这个函数执行很耗时,我有时候想要在它执行过程中中止它的执行,这种功能应该怎么实现?类似软件执行中有进度条,然后它可以取消回退到没执行之前的状态。

#include<iostream>
using namespace std;

#include<Windows.h>

class testClass {
public:
    void myfunction(int& a)
    {
        Sleep(100000); // 假如这个函数执行完会消耗100s
    }

    void stop() {
        // ?
    }
};


int main()
{
    testClass tc;
    int re = 10;
    tc.myfunction(re); // 在它运行过程中怎么调用tc的stop函数中止它的运行?
    
    return 0;
}

如果你的函数完全是在循环,在进行内存操作,你可以在循环里加个判断条件,如果取消执行就return
如果你的函数执行的是IO操作,比如写文件、读数据库、建立socket通信
那你只能杀死线程
不管是哪种方式,你至少要以线程的方式来执行函数
否则函数一运行,你UI整个卡死了,根本不会响应鼠标和键盘操作

这个问题没有标准的统一答案,要具体情况具体分析。

如果一个任务由多个操作(或循环)组成,添加退出点即可,比如启动一个 event ,如果超时了,外部设置该event,在任务内部,每一步要进行后续操作前判断一下event,如果有信号就终止、退出。
但如果是 IO类(文件、网络等)操作或者同步阻塞型的API调用,比如这里的Sleep,是没办法优雅的停下来的,只能强杀。但这样显而会有隐患。这就要考虑是否能分解这类任务,例如Sleep是否可以分解为多次短暂的Sleep,每次出来后判断条件是否该退出。对于文件读写,考虑异步的方式等。

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/1084693
  • 这篇博客也不错, 你可以看下虚函数是怎么实现多态的?虚表是什么?在虚函数实现时吗,虚表有什么作用(c++)
  • 除此之外, 这篇博客: C++函数参数的传递中的 简介:形参被定义为引用类型时被称为引用参数。引用参数对应的实参应该是对象名。函数被调用时,形参不需要开辟新的储存空间,形参名作为引用(别名)绑定于实参标识的对象上,执行函数体时,对形参的操作就是对实参对象的操作,直至函数执行结束,撤销引用绑定。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 代码如下(示例):

    #include<iostream>
    using namespace std;
    void swap(int &,int &);
    int main()
    {
    	int a=3,b=8;
    	cout<<"before swaping.....\n";
    	cout<<"a="<<a<<",b="<<b<<endl;
    	swap(a,b);
    	cout<<"after swaping.....\n";
    	cout<<"a="<<a<<",b="<<b<<endl;
    }
    void swap(int &x,int &y)
    {
    	int temp=x;
    	x=y;
    	y=temp;
    }
    
  • 您还可以看一下 夏曹俊老师的C++ 设计模式原理与实战大全-架构师需备课程课程中的 模板方法的定义场景与实现:将“动作”封装成对象是理解行为型模式的重要基础小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    要实现在C++中中止正在运行的函数并回到函数执行之前的状态,可以使用以下方法: 1. 使用多线程:将需要执行的函数放在一个单独的线程中,当需要中止函数执行时,可以通过调用线程的join()函数来中止线程的执行,并回到函数执行之前的状态。下面是一个示例代码:

    #include <iostream>
    #include <thread>
    
    // 定义一个标志变量,用于判断是否需要中止函数执行
    bool shouldTerminate = false;
    
    // 需要执行的函数
    void longRunningFunction() {
        // 在函数开始处检查标志变量,如果为true则中止函数执行
        if (shouldTerminate) {
            return;
        }
    
        // 执行函数的逻辑
        // ...
    
        // 在函数任意位置检查标志变量,如果为true则中止函数执行
        if (shouldTerminate) {
            return;
        }
    
        // 继续执行函数的逻辑
        // ...
    }
    
    int main() {
        // 创建新线程执行长时间运行的函数
        std::thread t(longRunningFunction);
    
        // 用户选择取消执行并中止函数的执行
        shouldTerminate = true;
    
        // 等待线程执行完成
        t.join();
    
        return 0;
    }
    
    1. 使用异常处理:在需要中止函数执行的地方抛出一个自定义的异常,然后在函数的catch块中捕获该异常,并回到函数执行之前的状态。下面是一个示例代码:
    #include <iostream>
    
    // 自定义的异常类
    class TerminateException {};
    
    // 需要执行的函数
    void longRunningFunction() {
        try {
            // 执行函数的逻辑
    
            // 在函数任意位置检查是否需要中止函数执行
            if (shouldTerminate) {
                throw TerminateException();
            }
    
            // 继续执行函数的逻辑
            // ...
        } catch (const TerminateException&) {
            // 中止函数执行后的处理逻辑,例如恢复到函数执行之前的状态
            // ...
        }
    }
    
    int main() {
        // 用户选择取消执行并中止函数的执行
        shouldTerminate = true;
    
        // 调用需要执行的函数
        longRunningFunction();
    
        return 0;
    }
    

    这些方法可以根据具体情况选择使用哪种方法来实现中止正在运行的函数并回到函数执行之前的状态。