c++ - QThread interthread communication: strange behavior connecting to &QThread::quit vs connecting to a lambda [&thread] { thread->quit();} -


i have following setup:

int main(int argc, char *argv[]) {     qcoreapplication a(argc, argv);      // create dbmanager live entire     // duration of application     auto dbmanagerthread = std::make_unique<qthread>();     auto dbmanager = std::make_unique<dbmanager>();     dbmanager->movetothread(dbmanagerthread.get());     dbmanagerthread->start();       // initialization of application, create     // inithelper object utilize dbmanager     auto inithelper = new inithelper();     auto inithelperthread = new qthread();     inithelper -> movetothread(inithelperthread);     // wire inithelper , thread     qobject::connect(inithelperthread, &qthread::started, inithelper, &inithelper::run);     qobject::connect(inithelper, &inithelper::finished, [&inithelperthread] { inithelperthread->quit();});     qobject::connect(inithelper, &inithelper::finished, inithelper, &inithelper::deletelater);     qobject::connect(inithelperthread, &qthread::finished, inithelperthread, &qthread::deletelater);      // wire inithelper , dbmanager     qobject::connect(inithelper, &inithelper::querydb, dbmanager.get(), &dbmanager::processquery);     qobject::connect(dbmanager.get(), &dbmanager::queryresult, inithelper, &inithelper::processqueryresult);       // block until information gathered     inithelperthread->start();     inithelperthread->wait();     std::cout << "initialization completed." << std::endl;      // cleanup     dbmanagerthread->quit();     qobject::connect(dbmanagerthread.get(), &qthread::finished, &a, &qcoreapplication::quit);     return a.exec(); } 

the idea have dbmanager doing asynchronous database accesses , hence utilized throughout entire application. during initialization of application need retrieve information database , i'd use existing dbmanager that.

however, since need information database create other objects, want block futher execution of main thread until inithelper has retrieved required information dbmanager.

since code above supposed to, don't think matters how inithelper , dbmanager implemented , have omitted them here.

what find confusing fact need use lambda in second line in 'wire inithelper , thread' part. if replace

qobject::connect(inithelper, &inithelper::finished, [&inithelperthread] { inithelperthread->quit();});

by

qobject::connect(inithelper, &inithelper::finished, inithelperthread, &qthread::quit);

apparently thread never shuts down , "initialization completed" never print stdout.

this output when using connection lambda:

inithelper: initialization started... dbmanager: processing query... inithelper: processing query result initialization completed. 

whereas when connecting slot directly, output:

inithelper: initialization started... dbmanager: processing query... inithelper: processing query result 

does know why there difference when connecting lambda instead of connecting slot directly? , how can write connect without lambda?

in code:

qobject::connect(inithelper, &inithelper::finished, [&inithelperthread] { inithelperthread->quit();}); 

is similar to:

qobject::connect(inithelper, &inithelper::finished, inithelperthread, &qthread::quit, qt::directconnection); 

it means directly calling function instead of using event loop.

the reason, believe, "correct" code not work (i.e. when use qt::queuedconnection - default) because have not started qt event loop running calling a.exec();

to solve this, remove wait() function , move "startup" code startup class (a bit inithelper). connect signal finished of inithelper start() function (or whatever want call it) of startup class.

edit

you might able (just read similar):

int ret = a.exec(); inithelperthread->wait(); std::cout << "initialization completed." << std::endl;     :   other stuff     : return ret; 

Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -