MoveToThread when original thread is unknown
-
So in short I'm building a service oriented system with remote methods which sequentially build up data (QObjects). These objects are later meant to be executed as individual varadic QScriptEngines with signals/slots.
The original design was to recursively use QtConcurrent::run(method) calls where 'method' contained a QEventLoop which handled events which worked fine. Eventually I ran out of threads with this approach and while trying to consolidate my QObject instances to run in a few QThreads vs individual threads left me stuck with the objects not being able to be moved to the new thread.
The problem is that the QObjects are created long before the QThread instances are created due to a remote-invocated construction algorithm so I'm trying to figure out how to move these QObjects which do not have parents into my new thread instance. The currently executing thread (RPC) is not of the originating thread so i'm kind of stuck without some backwards way of getting back to the creation thread to move the object. Does anyone have a good idea on how to accomplish this - as far as I know the creation thread is potentially destroyed or part of the main thread which isn't currently active.
Original code:
@
//This is part of a method that is executed by QtConcurrent::run(...)
// this method is part of the constructed QObject class long ago via RPC
QEventLoop eventLoop;
{
QWriteLocker guard(&m_actionDataLock);
m_startTime = MintUtils::Time::now();
}
// This MUST be queued so it hits the mutual exclusion of the script engine
connect( this, SIGNAL(signal_actionComplete2()), &eventLoop, SLOT(quit()), Qt::QueuedConnection);
setActionState(MintIDL::ExActionStateEnumNS::Started);
try
{
if(Invoke(engine)) //embedded method that does work
{
eventLoop.exec();
}
}
@My new approach is to make a Pool class which inherits from QThread and essentially calling 'Invoke' on a subset of tasks (tasks being the QObject instances that have moveToThread called on them) then calling exec() to handle the signals/slots which are emitted from the QScriptEngine - engine. The problem again is that the original QObject was created elsewhere and the thread is unknown. Calling moveToThread from the new invocation thread gives me the error about it not being the creation thread.
I'm kind of oblivious as how QEventLoop within a QtConcurrent task from the QApplication pool is able to work correctly.
-
Hi,
inherit from QThread is very tricky due to the allocation of memory in constructors etc that remains in the 'creator' thread and will not be moved with the object to the new thread. So I would not recommend this.
IF you need to parse an Object (QObject derived without a parent) you could register this type for Signal/Slot connections by using the Q_REGISTERE_METATYPE below your class definition (header file). You could do it anywhere, but in the header file below the class definition is IMHO the best location.
Then you are able to simple transfer the object via signal/slot.
That might help?