我想在一个事件中取消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被冻结,什么也没做。谢谢你的帮助!
答案 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)
。