Question

I would like to cancel a QtConcurent::map computation at an event.

This is my test code (the computation is represented by an infinite loop) :

class Test : public QObject
{
    Q_OBJECT

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

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

        //computation
        while(true);
    }
};

I have a list of Test, and I do :

//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)")

The goal is to cancel all the computation when the user click a button.

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

But when I click the button, the UI is freezed, and nothing is done. Thank's for help !

Was it helpful?

Solution 2

As Peppe said, QTConcurrent only cancels further processing (if you do map or filter over a sequence). A single item cannot be interrupted.

This is because Threads in general can't be canceled or interrupted.

In C++, you need to manage this yourself. (There was talk about extending C++ with the possibility to interrupt/cancel threads by pushing an exception to a thread, where it would throw, but the details were too hairy to get into the standard.)

For some languages that run a VM (Java, Python) it's doable when that thread is executing Java/Python code, but not when locked on a kernel/native) operation.

So, while(true) should be while(!m_interrupted).

OTHER TIPS

Apart from the fact that I would check if cancel does actually do something (that is, I wouldn't be surprised if it's not implemented), you're missing the point of it: it doesn't cancel the tasks currently running, but it prevents further tasks to be scheduled for that computation.

So if for instance you're running a map on 10 items (1 .. 10), and items 1 and 2 are being processed, and you invoke cancel, the ongoing computation on 1 and 2 will complete; possibly no further items will be processed (but you get no guarantees on that).

The problem, in general, is that you can't easily cancel a thread. For instance, Qt doesn't suppor it for QThreads.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top