gpt4 book ai didi

c++ - 如何杀死正在从外部库计算函数的线程

转载 作者:搜寻专家 更新时间:2023-10-31 02:20:42 24 4
gpt4 key购买 nike

我正在使用外部库来寻找最小的功能(优化)。有时它需要很多时间,我想停止计算(例如通过单击按钮)。所以我在另一个线程中进行优化。我见过的所有例子都做这样的事情(在 QThread 的子类中):

void run(){
for(int i=0;i<100000;i++){
if(!flag) break;
//do something
}
}

当主线程将标志设置为 false 时,第二个线程停止。问题是我不能将这样的标志放入外部库。但是,我提供了对要最小化的函数的引用,以便每次迭代都会调用该函数。所以我在那个函数中加入了标志:

double function(double x){
if(!flag) ;//here I should kill thread
return x*x*x+2*x*x+7*x+7;
}

那么如何杀死那个线程呢?

最佳答案

有两个问题:

  1. 如果在线程内运行的代码分配了任何资源(内存、文件句柄……),如果您 QThread::terminate,它们就会泄漏工作线程。

  2. 不清楚您的优化库是否有一套方法告诉它迭代要终止。如果库在你的控制之下,你应该简单地让它在获得 NaN 时停止迭代。来自函数。

您要查找的标志是QThread::isInterruptionRequested .要设置它,请调用 requestInterruption()在线程上。有许多可能的方式可以强制您的库终止迭代。您可以尝试以下操作:

  • 返回 std::numeric_limits<double>::quiet_NaN()来自函数:

    double function(double x){
    return isInterruptionRequested()
    ? std::numeric_limits<double>::quiet_NaN()
    : x*x*x+2*x*x+7*x+7;
    }
  • 从函数返回一个常量。

    double function(double x){
    return isInterruptionRequested()
    ? 0.0 : x*x*x+2*x*x+7*x+7;
    }
  • 将函数切换为在最近的值周围有一个全局最小值:

    class MyThread : public QThread {
    bool m_wasInterrupted;
    double m_minimum;
    double function(double x){
    if (!isInterruptionRequested())
    return x*x*x+2*x*x+7*x+7;
    if (!m_wasInterrupted) {
    m_minimum = x;
    m_wasInterrupted = true;
    }
    return abs(x-m_minimum) :
    }
    void run() {
    m_wasInterrupted = false;
    ...
    }
    };
  • 强制异常:

    class end_iteration_exception : public std::exception {};

    class MyThread : public QThread {
    ...
    double function(double x){
    if (isInterruptionRequested()) throw end_iteration_exception();
    return x*x*x+2*x*x+7*x+7;
    }
    void run() {
    try {
    ...
    } catch (const end_iteration_exception&) {
    // we've been interrupted
    }
    }
    };

优化库,如果用 C++ 编写,应该采用仿函数,因此您会传递它 std::bind(&MyThread::function, this)来自内部 run() .

如果没有,而是有一个只接受函数指针的 C api,那么它应该提供一个版本,让您将常量参数作为第二个参数传递给函数:

double findMinimum(double (*fun)(double, void*), void * param) {
...
double val = fun(x, param);
...
return x;
}

然后您的函数将采用第二个参数来表示线程实例:

class MyThread {
static double function(double x, void* p){
auto self = reinterpret_cast<MyThread*>(p);
return self->isInterruptionRequested()
? 0.0 : x*x*x+2*x*x+7*x+7;
}
void run() {
...
auto x = findMinimum(&function, this);
...
}
...
};

如果它甚至不这样做,那么您只能求助于全局状态:

class MyThread;
namespace {
MyThread * threadState { nullptr };
}

class MyThread : public QThread {
...
void run() {
threadState = this;
...
threadState = nullptr;
}
static double function(double x) {
return threadState->isInterruptionRequested() ? ...;
}
};

关于c++ - 如何杀死正在从外部库计算函数的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32378047/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com