0

我想在事件中取消 QtConcurent::map 计算。

这是我的测试代码(计算由无限循环表示):

class Test : public QObject
{
    Q_OBJECT

public:
    Test(QObject *parent=0) : QObject(parent){}

    void test()
    {
        qDebug() << tr("thread:") <<  QThread::currentThread();

        //computation
        while(true);
    }
};

我有一个测试列表,我这样做:

//QFuture<void> m_concurentResult;
m_concurentResult = QtConcurrent::map(m_collection, &Test::test);
//That's Ok, I have the two outputs :
//  QThread(0x4e21f8, name = "Thread (pooled)")
//  QThread(0x4e21b8, name = "Thread (pooled)")

目标是在用户单击按钮时取消所有计算。

void Widget::on_pushButton_clicked()
{
    m_concurentResult.cancel();
    m_concurentResult.waitForFinished();
}

但是当我单击按钮时,用户界面被冻结,什么也没做。感谢帮助 !

4

2 回答 2

1

除了我会检查是否cancel确实做某事(也就是说,如果它没有实现我不会感到惊讶),你错过了它的重点:它不会取消当前正在运行的任务,但它防止为该计算安排进一步的任务。

因此,例如,如果您正在对 10 个项目(1 .. 10)运行地图,并且正在处理项目 1 和 2,并且您调用取消,则对 1 和 2 的正在进行的计算将完成;可能不会再处理其他项目(但您无法保证)。

一般来说,问题在于您不能轻易取消线程。例如,Qt 不支持 QThreads。

于 2014-01-22T16:03:40.490 回答
0

正如 Peppe 所说,QTConcurrent 只会取消进一步的处理(如果您对序列进行映射或过滤)。单个项目不能被打断。

这是因为线程通常不能被取消或中断。

在 C++ 中,您需要自己管理它。(有人讨论过扩展 C++ 以通过将异常推送到会抛出的线程来中断/取消线程的可能性,但细节太繁琐以至于无法进入标准。)

对于某些运行 VM(Java、Python)的语言,当该线程正在执行 Java/Python 代码时是可行的,但在锁定在内核/本机操作时则不行。

所以,while(true)应该是while(!m_interrupted)

于 2014-01-22T16:14:09.437 回答