Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QThreadPool force stop in qt cpp

Tags:

c++

qt

I have created Qthreadpool . i want to remove all the task from the queue. The code is below.

void MainWindow::startThread()
{
   thread= new QThradPool(this);
   thread->setMaxThreadcount(1);
   hello = new HelloWordTask();
   thread->start(hello);
}
void MainWindow::stopThread()
{
  thread->clear();
  delete thread;
  delete hello;
  // but current task is not stopping. until it is finished. i want to stop it 
   immediately .
}
void HelloWordTask::run()
{
  // function which takes time
}
like image 968
mahesht Avatar asked Apr 18 '26 07:04

mahesht


1 Answers

It is not generally possible. Some QFutures - not the ones returned by QtConcurrent::run, though - are cancellable. If you're using QtConcurrent::run, or submitting a generic QRunnable, you need to make it cancellable. This answer provides a way of generating a cancellable future that runs on the thread pool. You then need to keep track of those futures and cancel any that are in progress.

Generally speaking, there's no need to dynamically create the thread pool - just store it by value. And once you use a QFuture interface, there's no need to manage the lifetime of the tasks either: the futures are handles for this object, and once the last one goes away, the task object is released.

class HelloWorldTask : RunControllableTask<void> {
  // see https://stackoverflow.com/a/16729619/1329652
  ...
};

class MainWindow : public QMainWindow {
  QThreadPool m_pool;
  QVector<QFuture<void>> m_futures;
public:
  explicit MainWindow(QWidget * parent = {}) : QMainWindow(parent) {
    m_pool.setMaxThreadCount(1);
  }
  void startTask() {
    auto future = TaskExecutor::run(new HelloWorldTask());
    m_futures.push_back(future);
  }
  void stopAllTasks() {
    m_pool.cancel();
    for (auto &future : m_futures)
      future.cancel();
    while (!m_futures.isEmpty())
      m_futures.takeLast().waitForFinished(); // this will free the task too!
    Q_ASSERT(!m_pool.activeThreadCount());
  }
  ~MainWindow() override {
    stopAllTasks();
  }
};

You can use the future interface to thread-safely return data back from the task, too!

like image 63
Kuba hasn't forgotten Monica Avatar answered Apr 19 '26 21:04

Kuba hasn't forgotten Monica