Motivation for multithreading in my App
-
Ok, this is how I transformed my code:
In main.cpp:
int main(int argc, char* argv[]) { Controller controller(argc, argv); return controller.runApplication(); }And in Controller:
Controller::Controller(int argc, char* argv[]) : _app(argc, argv) { // does nothing } void Controller::initModule() { _devicesManager = new DevicesManager; _moduleThread = new QThread(this); // Controller will be the parent of QThread - and will be responsible for deleting it _devicesManager->moveToThread(_moduleThread); _moduleThread->start(); } void Controller::initView() { _gui = new GUI; } int Controller::runView() { _gui->show(); return _app.exec(); } void Controller::connectSignals() { connect(_moduleThread, SIGNAL(started()), _devicesManager, SLOT(start())); // more to come, for now just connecting QThread's 'started' signal to DevicesManager::start() } int Controller::runApplication() { initModule(); initView(); connectSignals(); return runView(); }For now,
DeviceManagerdoes absolutely nothing, except this:void DevicesManager::start() { qDebug() << "Starting!"; }(that's why I didn't bother to connect
QThread::finishedtoDeviceManager::deleteLaterfor now - because it holds no memory allocation)But I am experiencing two problems:
- When I run it, the GUI runs fine, but then when I close the GUI by clicking the x button of the window, I get:
QThread: Destroyed while thread is still running - I don't see the "Starting!" printed out to the console, which makes me think that start didn't really run, not to mention running on a different thread...
- When I run it, the GUI runs fine, but then when I close the GUI by clicking the x button of the window, I get:
-
Ok, this is how I transformed my code:
In main.cpp:
int main(int argc, char* argv[]) { Controller controller(argc, argv); return controller.runApplication(); }And in Controller:
Controller::Controller(int argc, char* argv[]) : _app(argc, argv) { // does nothing } void Controller::initModule() { _devicesManager = new DevicesManager; _moduleThread = new QThread(this); // Controller will be the parent of QThread - and will be responsible for deleting it _devicesManager->moveToThread(_moduleThread); _moduleThread->start(); } void Controller::initView() { _gui = new GUI; } int Controller::runView() { _gui->show(); return _app.exec(); } void Controller::connectSignals() { connect(_moduleThread, SIGNAL(started()), _devicesManager, SLOT(start())); // more to come, for now just connecting QThread's 'started' signal to DevicesManager::start() } int Controller::runApplication() { initModule(); initView(); connectSignals(); return runView(); }For now,
DeviceManagerdoes absolutely nothing, except this:void DevicesManager::start() { qDebug() << "Starting!"; }(that's why I didn't bother to connect
QThread::finishedtoDeviceManager::deleteLaterfor now - because it holds no memory allocation)But I am experiencing two problems:
- When I run it, the GUI runs fine, but then when I close the GUI by clicking the x button of the window, I get:
QThread: Destroyed while thread is still running - I don't see the "Starting!" printed out to the console, which makes me think that start didn't really run, not to mention running on a different thread...
- When I run it, the GUI runs fine, but then when I close the GUI by clicking the x button of the window, I get:
-
hi, @Absurd
you start your QThread object before you do the connection -> started signal is emitted before the connection is made -> slot gets not invoked.
_moduleThread->start();
-
@J.Hilk ohh... how silly of me... :
Thank you.Do you know what could be the cause for the second thing?
QThread: Destroyed while thread is still running@Absurd said in Motivation for multithreading in my App:
@J.Hilk ohh... how silly of me... :
Thank you.Do you know what could be the cause for the second thing?
QThread: Destroyed while thread is still runningCall
QThread::quitand after thatQThread::waitbefore you exit the application.Addendum:
What is a good justification to use threads anyway?
Latency. Having a slow, blocking or otherwise high latency operation you don't need or want to wait for - you need to thread it, otherwise you do not.
-
@Absurd said in Motivation for multithreading in my App:
@J.Hilk ohh... how silly of me... :
Thank you.Do you know what could be the cause for the second thing?
QThread: Destroyed while thread is still runningCall
QThread::quitand after thatQThread::waitbefore you exit the application.Addendum:
What is a good justification to use threads anyway?
Latency. Having a slow, blocking or otherwise high latency operation you don't need or want to wait for - you need to thread it, otherwise you do not.
@kshegunov thanks for your reply. appreciate it.
@kshegunov said in Motivation for multithreading in my App:
Call QThread::quit and after that QThread::wait before you exit the application.
I should call
QThread::quit&QThread::waitfromController's destructor, right? -
@kshegunov thanks for your reply. appreciate it.
@kshegunov said in Motivation for multithreading in my App:
Call QThread::quit and after that QThread::wait before you exit the application.
I should call
QThread::quit&QThread::waitfromController's destructor, right?@Absurd said in Motivation for multithreading in my App:
I should call QThread::quit & QThread::wait from Controller's destructor, right?
Yes, that is correct. You should also free your worker objects:
QObject::connect(_moduleThread, &QThread::finished, _devicesManager, &QObject::deleteLater); -
@Absurd said in Motivation for multithreading in my App:
I should call QThread::quit & QThread::wait from Controller's destructor, right?
Yes, that is correct. You should also free your worker objects:
QObject::connect(_moduleThread, &QThread::finished, _devicesManager, &QObject::deleteLater);@kshegunov why not just
delete _deviceManagerafterQthread::wait()has returned?@MrShawn said:
No, the first QString is like a "key" for your message type, so that you know what keys to look for or are available in your QVariantMap.
Can you please give a usage example for that?
I couldn't figure out why isn'tvoid message(QString, QVariant)enough... -
@kshegunov why not just
delete _deviceManagerafterQthread::wait()has returned?@MrShawn said:
No, the first QString is like a "key" for your message type, so that you know what keys to look for or are available in your QVariantMap.
Can you please give a usage example for that?
I couldn't figure out why isn'tvoid message(QString, QVariant)enough...@Absurd said in Motivation for multithreading in my App:
@kshegunov why not just
delete _deviceManagerafterQthread::wait()has returned?It's possible, but it still belongs to the worker thread, you may get warnings.
-
@kshegunov why not just
delete _deviceManagerafterQthread::wait()has returned?@MrShawn said:
No, the first QString is like a "key" for your message type, so that you know what keys to look for or are available in your QVariantMap.
Can you please give a usage example for that?
I couldn't figure out why isn'tvoid message(QString, QVariant)enough...void message(QString msgType, QVariantMap data);QVariantMap not QVariant.
QVarantMap is a map with QStrings for keys, so like say you emit a signal that is declared like above, it may look something like this.
QVariantMap params; int param1 = 2; double param2 = 2.2; params.insert("param1",param1); params.insert("param2",param2); emit message("runSomeSpecificMethod",params);Then the receiving slot may look something like this
void getMessage(QString messageType, QVariantMap data) { if (messageType.compare("runSomeSpecificMethod",Qt::CaseInsensitive) == 0){ SomeSpecificMethod(data.value("param1").toInt(),data.value("param2").toDouble()); } }