Qt-如何杀死QThread
我正在尝试终止/取消一个QThread。我跟踪了该计划的实施情况 我创建的QThread如下所示:Qt-如何杀死QThread,qt,Qt,我正在尝试终止/取消一个QThread。我跟踪了该计划的实施情况 我创建的QThread如下所示: workerThread = new QThread(); ImageProcessor* worker = new ImageProcessor(); worker->moveToThread(workerThread); connect(workerThread, SIGNAL(started()), worker, SLOT(process())); connect(worker, S
workerThread = new QThread();
ImageProcessor* worker = new ImageProcessor();
worker->moveToThread(workerThread);
connect(workerThread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), workerThread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
workerThread->start();
class ImageProcessor : public QObject
{
Q_OBJECT
public:
explicit ImageProcessor(QObject *parent = 0);
~ImageProcessor();
signals:
void finished();
public slots:
void process();
private:
//...
};
并尝试通过调用以下命令在某个UI事件上停止它:
workerThread->quit();
我的工人看起来像这样:
workerThread = new QThread();
ImageProcessor* worker = new ImageProcessor();
worker->moveToThread(workerThread);
connect(workerThread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), workerThread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
workerThread->start();
class ImageProcessor : public QObject
{
Q_OBJECT
public:
explicit ImageProcessor(QObject *parent = 0);
~ImageProcessor();
signals:
void finished();
public slots:
void process();
private:
//...
};
其中,进程调用一个计算量很大的API
void ImageProcessor::process()
{
// API call...
emit finished();
}
我的问题是,在线程上调用quit之后,线程继续运行,即API的计算不会停止。因为worker只调用API,所以我无法在worker循环中使用cancel检查。有什么想法吗
提前谢谢
API的计算没有停止
所以你在计算的时候试图阻止它
QThread::quit仅在计算完所有内容后停止
您可以将计算拆分为更小的任务,甚至可以添加取消标志。在ImageProcessor对象上使用普通方法进行设置:
class ImageProcessor{
void stop(){
canceled = true;
}
private:
bool canceled;
}
然后检查是否(取消)退货;在进程槽中。(只写bool是线程安全的)
然后调用stop();无法停止已阻止的QThread,至少不能以任何安全方式停止 例如,如果您已输入此函数
void neverStop() {
int *arr = new int[1024*1024];
for (;;) {
}
}
线程不会响应任何退出消息,虽然大多数操作系统都有强制终止线程的方法,但任何分配的内存都不会被正确释放。不要使用
thread->quit()。通过这种方式,您可以从内部正确地停止工作程序,例如停止处理并发出finished()信号
您可以通过在工作程序中实现用于取消的插槽(例如插槽\u cancelWorker()
)来设置该标志。然后,您可以将其与GUI连接:
connect(myPushButton, SIGNAL(clicked()), worker, SLOT(slot_cancelWorker()));
当然,在处理函数中,必须检查挂起的事件。因此,您必须定期调用QCoreApplication::processEvents()
您繁重的任务非常简单,我会使用QtConcurrent::run
而忘记QThread
ImageProcessor* worker = new ImageProcessor();
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
QtConcurrent::run(worker, &ImageProcessor::process);
这正是您所需要的,而且速度会更快,因为它将使用线程池中的线程,而不是创建一个新线程
只需记住使用Qt::AutoConnection
(默认值)
要优雅地停止处理,您必须在处理方法中对某些变量进行极化:
bool ImageProcessor::needEndNow() {
QMutexLocker locker(mutex);
return endNowRequested;
}
void ImageProcessor::requestEndNow() {
QMutexLocker locker(mutex);
endNowRequested = true;
}
void ImageProcessor::process()
{
while(!needEndNow()) {
// nextStep of processing
}
emit finished();
}
如果您有类似的东西,没有任何循环:
void ImageProcessor::process()
{
worker_api(); // that takes a lot of time
emit finished();
}
对于QThread,您几乎无能为力。你可以做,从更好到最坏:
- 可能您正在使用的API有另一个调用来停止该工作调用。但是既然你在这里问,我想没有这样的事情
- 在不再需要时,使用
QProcess
和kill
从不同的进程启动辅助进程调用。优点:不用担心清洁。相反:检索结果可能很困难
QThread::terminate
,但未经建议(请参阅:基本上,无清理)
- 在Windows中,
QThread::currentThreadId
为您提供了一个可以用于其他操作系统调用的号码(请参阅)
这里的问题是,我只调用一个进行大量计算的API函数。我不能把它分解成更小的碎片,因此也不能检查它是否被取消。API开始了它自己的生活,我不知道如何阻止它…为什么不让它运行呢?如果调用workerThread->setPriority(QThread::IdlePriority)
它也不会使用很多resource…您可以运行线程直到结束,如果cancelled
为true,则不会发出完成信号。看看这个答案-,它可能对您有用