我有一些任务,从QtConcurrent::run()开始。任务有QFutureWatcher。我知道QFutureWatcher只能监视的一个未来,但是当我从UI启动相同的任务时,我如何在每个任务上创建‘`QFutureWatcher*?是:
QFutureWatcher<void> *watcher = new QFutureWatcher;
watcher->setFuture(future);
QVector<QFutureWatcher<void>*> watchers;
watchers.push_back(watcher); // vector with pointers to each tasks watchers或者别的什么?*我的麻烦在于,我从代码中启动每个任务,但是任务使用外部DLL函数执行。我没有API来停止这个任务。我只能等待任务结束和关闭任务与释放所有相关数据,在我收到完成后的QFutureWatcher信号。
此时,我使用两个QFutureWatchers -一个是监视第一个运行的任务,另一个是如果第一个任务还没有结束就启动,并使用临时监视器和临时时隙来监视第二个任务(代码相同,我创建它只是为了接收具有相关数据的另一个观察信号),直到第一个任务结束。它监视相同的代码,但是我必须复制它,因为等待第一个任务已经结束,因为QFutureWatcher没有包含已完成信号和相关的watcher.result()的队列。
1) Qt是否有排队任务机制?或者我如何捕捉未来的多个任务?
2) QtConcurrent::run没有cancel()槽。我可以使用带一个序列项的映射/映射函数吗?映射的API是否已排队处理任务/已完成的信号?我怎么能意识到这一点?谢谢!
发布于 2016-07-13 08:52:54
1)您可以使用这样的内容(只是代码草案):
class MultiWatcher
: public QThread
{
Q_OBJECT
signals:
void allDone();
public:
void run() override;
QFutureSynchronizer _sync;
};
void MultiWatcher::run()
{
_sync.waitForFinished();
emit allDone();
}
class Test
: public QObject
{
Q_OBJECT
public:
//...
void do();
void onDone();
};
void Test::do()
{
// fill some futures
auto w = new MultiWatcher();
w->_sync.addFuture( f1 ); // Not thread-safe
w->_sync.addFuture( f2 );
w->_sync.addFuture( f3 );
// ...
connect( w, &MultiWatcher::allDone, this, &Test::onDone );
w->start();
}
void Test::onDone()
{
sender()->deleteLater();
qDebug() << "All futures are done";
}
//...
test->do();2)对于映射的QFuture::cancel()方法,从你的问题上看还不清楚,你是如何得到未来的,所以很难多说。如果你有一些问题,你可以阅读Qt中的并发性,并提出更多的问题。
QFuture::cancel不能使用QtConcurrent::run,您需要在线程代码中设计另一个中断机制。例如:
std::atomic_bool _isRunning = true; // somewhere in code
void MyWorker::doWork()
{
while (_isRunning)
{
// Do next step of computation
}
}
// Use _isRunning = false; to interrupt. It's thread-safe.但是中断您不管理的代码(从外部.dll)是有风险的,因为您可能有很多泄漏。这就是为什么在QtConcurrent中没有“终止”API的原因。
P.S.,请不要写我对QThread做错了。一切都很好。我自己知道要做什么。这是一个很好的示例,在这里QThread的继承是可以的。
发布于 2016-07-13 09:31:30
Qt是否有排队的任务机制?
Qt提供了一个强大的信号和插槽框架,这对于这样的应用程序来说是完美的。
执行步骤:
executeTask(int foo, QString bar)。QThread并使用QObject::moveToThread将Worker类实例移动到该QObject::moveToThreadexecuteTask的信号或通过调用executeTask方法上的QMetaMethod::invoke来运行任务。备注:
executeTask的调用进行排队(只要使用4中描述的方法之一)。他们将按顺序执行死刑。QThread::requestInterruption,并在使用QThread::isInterruptionRequested的executeTask方法中检查是否取消。QThread::terminate。QThread::quit和QThread::wait来优雅地终止工作人员,并等到所有任务都执行完毕。https://stackoverflow.com/questions/38345474
复制相似问题