Details
-
Bug
-
Resolution: Invalid
-
P2: Important
-
None
-
5.15.2
-
None
-
Windows 10, MSVC2019 x64
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