У меня есть несколько задач, началось с QtConcurrent::run()
,
Задачи имеет QFutureWatcher
, я знаю это QFutureWatcher
можно посмотреть только один Будущее, но когда я запускаю те же задачи из пользовательского интерфейса, как я могу создать `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 () `s ..
1) Есть ли в Qt какой-либо механизм задач в очереди? или как я могу поймать несколько задач на будущее?
2) QtConcurrent::run
не имеет слота cancel (). Могу ли я использовать функции map / mapped с одним элементом последовательности? Имеет ли отображенный API очередь обработки задач / завершенных сигналов? Как я могу это понять? Спасибо!
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 завершения.
Постскриптум Пожалуйста, не пишите это Я делаю это неправильно с QThread. Там все хорошо. Я знаю, что я делаю. Это хороший образец, где наследование QThread
все в порядке.
Есть ли в Qt какой-либо механизм задач в очереди?
Qt предоставляет мощный сигнал&слот каркаса, который идеально подходит для такого применения.
Шаги реализации:
executeTask(int foo, QString bar)
который содержит реализацию задачи.QThread
и переместите ваш экземпляр класса Worker в этот QThread, используя QObject::moveToThread
executeTask
или по телефону QMetaMethod::invoke
на executeTask
метод.Заметки:
executeTask
(при условии, что вы используете один из методов, описанных в 4.), и они будут выполняться по порядку. QThread::requestInterruption
и проверьте отмену в вашем executeTask
метод с использованием QThread::isInterruptionRequested
,QThread::terminate
,QThread::quit
а также QThread::wait
изящно уволить работника и ждать, пока все задачи не будут выполнены.