取消QtConcurent计算

时间:2014-01-22 15:50:14

标签: c++ qt qtconcurrent

我想在一个事件中取消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);
    }
};

我有一个Test列表,我这样做:

//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();
}

但是当我点击按钮时,UI被冻结,什么也没做。谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

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

因此,如果您正在运行10个项目(1 ... 10)上的地图,并且正在处理项目1和2,并且您调用取消,则将完成对1和2的正在进行的计算;可能没有其他项目会被处理(但你没有得到任何保证)。

问题一般是你不能轻易取消一个帖子。例如,Qt不支持QThreads。

答案 1 :(得分:0)

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

这是因为一般情况下线程无法取消或中断。

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

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

因此,while(true)应为while(!m_interrupted)