QtConcurrent and moveToThread
-
Hi,
In my application, the whole user work session is managed by a graph of QObjects.
I have a write/read function to save/load the user work session from/to an xml file.
So, when the read function is executed, the xml file is parsed and QObjects are created to restore the user work session.
Everything works correcly... but... with a big xml file, the loading time can be long (10s-30s, also due to other ressources loading and some pre-processing), so I would like to load the file from a worker thread (so the GUI isn't freezed)
To do that, I use "QtConcurrent::run" to execute the read function, but I'm facing a problem : all QObjects created by the read function belongs to the QtConcurrent worker thread.
I tried to "moveToThread" all objects to the "QApplication::instance()->thread()" while they are created by the read function.
The problem is only partially solved. For example if we have "A" class with constructor defined as following :
@A::A()
{
p_mySocket = new QTcpSocket();
}@Then the read function read an "A" instance from the XML file and execute :
@
...
XML parsing
...
Found "A" instance tag
...
A* pA = new A();
pA->moveToThread(QApplication::instance()->thread())
...
XML parsing
...
@=> the problem is about the "p_mySocket " object : it still belongs to the QtConcurrent worker thread.
=> I can't editall my classes to implement a "moveToMainThread" method which move all the class members to the main threadSo my questions are :
1/ is there anyway to move ALL objects that belongs to a thread to another ?
2/ is there anyway to know the list of ALL objects that belongs to a specific thread ? (for debugging purpose : check if all objects have been moved to the main thread)
3/ after the "QtConcurrent::run" execution finished, is the worker thread deleted ? So what happen to all objects that belongs to this thread ?
Thanks.
-
- if you create all your QObjects in the worker threads on the heap and then put the pointers to those objects in a QList owned by an object that resides in your main thread I don't see any problems. The QObjects will be alive until you explicitly call delete on them (with the exception that, if these QObjects have a parent, they are deleted when their parent is deleted). Finally you can iterate over the list and move every object to the main thread context.
-
The problem is that all objects created in the worker thread belongs to this thread.
Because this thread is deleted (or no more running, i'm not sure) after the “QtConcurrent::run” execution finished, there is no more event loop executed for this thread, and SIGNAL/SLOT can never be receive/send from/to these objects.
(executing "connect" without the connection type will make a QueuedConnection, and because of the lack of an event loop, the message is never received)
This break SIGNAL/SLOT functionnality, and have other side effects.
For the moment, my main goal is to write a function which check if I didn't forget to move an object to the main thread.
-
You could create the objects inside the others with a parent pointer:
@
A::A()
{
p_mySocket = new QTcpSocket(this);
}
@This would also take those to the main thread.
-
Yes, but the problem is that I have about hundred classes to check, and I did'nt write all of them... so I need at least an automatic check.
-
AFAIK, there is no automatic check, sorry.
From my POV, if it is a requirements to go that way, you must change the code as these are programming errors in that case.
-
bq. you must change the code as these are programming errors in that case
I agree, but in front of the huge number of files, I cannot be sure that no object was not moved to the main thread.
-
I know such things, but I have no other proposal then:
check each usage and file :-(