#cpp #qt #qt5
Использую QThreadPool и QRunnable. Как завершить работу QRunnable, если тот из очереди уже перешёл в состояние выполнения? В QThreadPool имеется метод, позволяющий изымать из пула объекты выполнения, но только тех из них, что всё ещё находятся в очереди. По идее, в наследнике QRunnable нужен некий флаг (наподобие QThread::requestInterruption()), который можно было бы переключать из вне, а уже объект выполнения смотрел бы время от времени значение этого флага. Соответственно, если настала пора закругляться, то и завершал бы свою работу. Однако в этом случае нужно хранить список объектов QRunnable, чтобы иметь возможность установки флага, и в итоге иметь вероятность краха программы, если QThreadPool кого-либо из них заблаговременно уничтожит. Отказываться от QRunnable::autoDelete() == true совсем не хочется. Есть ли возможность как-то решить эту проблему, не уходя в сторону QThread и не изменяя QRunnable::autoDelete() == true, так как уж очень подкупает удобство использования QThreadPool?
Ответы
Ответ 1
Если Вас не устраивает функция отмены в наследнике QRunnable, тогда можно сделать по другому. Пусть наследник имеет конструктор, который принимает указатель на QAtomicInteger. Ещё будет конструктор, которые не будет принимать этот указатель — по умолчанию, в классе, он будет равен nullptr. Внутри метода run если указатель не нулевой, и его значение по указателю(полученное через load()) равно, скажем, 1, тогда задание было отменено и мы немедленно завершаем выполнение. Как Вы уже поняли, этот указатель будет предоставляться тем кодом, что создаёт QRunnable и его значение будет выставляться там же. Код может выглядеть так: class MyRunnable: public QRunnable { public: MyRunnable(QAtomicInteger* cancelationToken): m_CancelationToken{cancelationToken} { } void run() override { while(true) { if(m_CancelationToken && m_CancelationToken->load() == 1) return; } } private: QAtomicInteger* m_CancelationToken = nullptr; }; Где-то в коде: QAtomicInteger cancel; auto runnable = new MyRunnable(&cancel); ... cancel = 1;
Комментариев нет:
Отправить комментарий