Я хотел бы отменить вычисление 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();
}
Но когда я нажимаю на кнопку, пользовательский интерфейс останавливается, и ничего не делается. Спасибо за помощь !
Как сказал Пеппе, QTConcurrent только отменяет дальнейшую обработку (если вы делаете карту или фильтруете последовательность). Один предмет не может быть прерван.
Это потому, что потоки в целом не могут быть отменены или прерваны.
В C ++ вам нужно управлять этим самостоятельно. (Говорилось о расширении C ++ с возможностью прерывать / отменять потоки, помещая исключение в поток, куда он будет добавлен, но детали были слишком сложными, чтобы войти в стандарт.)
Для некоторых языков, в которых запущена виртуальная машина (Java, Python), это возможно, когда этот поток выполняет код Java / Python, но не при блокировке на ядре / нативной операции.
Так, while(true)
должно быть while(!m_interrupted)
,
Помимо того, что я бы проверил, если cancel
действительно что-то делает (то есть я не удивлюсь, если это не будет реализовано), вы упускаете суть: это не отменяет задачи, которые выполняются в данный момент, но предотвращает планирование дальнейших задач для этого вычисления ,
Так, например, если вы запускаете карту из 10 элементов (1 … 10), а элементы 1 и 2 обрабатываются, и вы вызываете отмену, текущие вычисления для 1 и 2 будут завершены; возможно, никакие другие предметы не будут обработаны (но вы не получите никаких гарантий).
Проблема, как правило, в том, что вы не можете легко отменить поток. Например, Qt не поддерживает его для QThreads.