我想在事件中取消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();
}
但是当我点击这个按钮时,UI就被冻结了,什么也没做。谢谢你的帮助!
发布于 2014-01-22 08:14:09
正如Peppe所说,QTConcurrent只会取消进一步的处理(如果您对序列进行映射或筛选)。不能中断单个项目。
这是因为线程一般不能被取消或中断。
在C++中,您需要自己管理。(关于扩展C++,可以通过将异常推送到线程中来中断/取消线程,但细节太复杂,无法进入标准。)
对于某些运行VM (Java,Python)的语言来说,当线程执行Java/Python代码时是可行的,而当锁定在内核/本机操作时则不行。
所以,while(true)
应该是while(!m_interrupted)
。
发布于 2014-01-22 08:03:40
除了我会检查cancel
是否真的做了一些事情(也就是说,如果它没有实现,我就不会感到惊讶),您还忽略了它的要点:它没有取消当前正在运行的任务,但是它阻止了为该计算计划更多的任务。
例如,如果你在10项上运行一张地图(1 .),并且正在处理项目1和2,并且调用cancel,正在对1和2进行的计算将完成;可能不会处理更多的项(但在这方面您得不到任何保证)。
问题是,一般来说,你不能轻易取消一个线程。例如,Qt不支持QThreads。
https://stackoverflow.com/questions/21287595
复制相似问题