Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-96252

QtConcurred spawned threads have same ID as main thread when waitForFinished() is used

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Invalid
    • Affects Version/s: 5.15.2
    • Fix Version/s: None
    • Component/s: Core: Threads
    • Labels:
      None
    • Environment:
      Windows 10, MSVC2019 x64
    • Platform/s:
      Windows

      Description

      Creating new threads with QtConcurrent will create new threads with ID different from the main thread, unless waitForFinished() is called.

      Here is a minimal test, where I spawn a QtConcurrent on button click. The run method updates a counter on a spinbox.

      #include "MainWindow.h"
      #include "ui_MainWindow.h"
      #include <QDebug>
      #include <QThread>
      #include <qtconcurrentrun.h>

      MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui_(new Ui::MainWindow)
        , cnt_(0)
      {
        ui_->setupUi(this);
        connect(this, &MainWindow::setSpinBoxValue, ui_->spinBox, &QSpinBox::setValue);

        qDebug() << "MainWindow() thread ID: " << QThread::currentThreadId();
      }

      MainWindow::~MainWindow()
      {
        qDebug() << "~MainWindow() thread ID: " << QThread::currentThreadId();

        delete ui_;
      }

      void MainWindow::on_pushButton_clicked()
      {
        qDebug() << "on_pushButton_clicked() thread ID: " << QThread::currentThreadId();

        QFuture<void> th = QtConcurrent::run(this, &MainWindow::updateValue);

        // TEST MADE ENABLING/DISABLING THE FOLLOWING LINE
        th.waitForFinished();
      }

      void MainWindow::updateValue()
      {
        qDebug() << "updateValue() thread ID: " << QThread::currentThreadId();

        emit setSpinBoxValue(++cnt_);
      }

       

      If I remove/comment th.waitForFinished() line the debug output shows different IDs for the click thread (main thread) and the concurrent thread, as expected:

      14:38:17: Debugging starts
      MainWindow() thread ID: 0x1ad0
      on_pushButton_clicked() thread ID: 0x1ad0
      updateValue() thread ID: 0xc40
      on_pushButton_clicked() thread ID: 0x1ad0
      updateValue() thread ID: 0xc40
      on_pushButton_clicked() thread ID: 0x1ad0
      updateValue() thread ID: 0xc40
      ~MainWindow() thread ID: 0x1ad0
      14:38:27: Debugging has finished

      If I wait for thread termination (th.waitForFinished() called), the concurrent runs in a new thread the first time, then runs on the main GUI thread on all successive callss:

      14:40:23: Debugging starts
      MainWindow() thread ID: 0x764
      on_pushButton_clicked() thread ID: 0x764
      updateValue() thread ID: 0x83c
      on_pushButton_clicked() thread ID: 0x764
      updateValue() thread ID: 0x764
      on_pushButton_clicked() thread ID: 0x764
      updateValue() thread ID: 0x764
      ~MainWindow() thread ID: 0x764
      14:40:35: Debugging has finished

      Why is this happening?

       

      The behavior is correct again if I force QtConcurrent::run() to run in a new  QThreadPool:

      void MainWindow::on_pushButton_clicked()
      {
        qDebug() << "on_pushButton_clicked() thread ID: " << QThread::currentThreadId();

        QThreadPool pool;

        QFuture<void> th = QtConcurrent::run(&pool, this, &MainWindow::updateValue);

        th.waitForFinished();
      }

      Output:

      19:14:28: Debugging starts
      MainWindow() thread ID: 0x1b64
      on_pushButton_clicked() thread ID: 0x1b64
      updateValue() thread ID: 0x1084
      on_pushButton_clicked() thread ID: 0x1b64
      updateValue() thread ID: 0x1768
      on_pushButton_clicked() thread ID: 0x1b64
      updateValue() thread ID: 0x6c
      on_pushButton_clicked() thread ID: 0x1b64
      updateValue() thread ID: 0x7c
      ~MainWindow() thread ID: 0x1b64
      09:14:34: Debugging has finished

       

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            thiago Thiago Macieira
            Reporter:
            massimo.cristofolini Massimo Cristofolini
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes