Question

So if I understand correctly, If I have a class FunctionsClassthat inherits QObject and i set that class up on a Qthread called FunctionClassThreadby doing:

FunctionsClass classObj; 
classObj.moveToThread( &FunctionClassThread );
FunctionClassThread.start();

From what I understand this method of setting up a thread will only handle the execution of slots in the FunctionsClass, which means the thread running FunctionsClass can be blocked if a slot in FunctionsClass for some reason has a infinite loop.

So my questions are: How can I run the functions of FunctionsClass on a thread not just the slots? Is there a way to place a whole object (functions, member variables, etc) on a thread for execution of code/data from that whole object only? And is my understanding of how the thread will handle the execution of slots correct?

Was it helpful?

Solution

When you execute a method of an object it is executed in the thread you're invoking the method. It doesn't matter where the QObject is living.

If you want to invoke a method so that it is executed in another thread asynchronously you'll have to handle the situation so that the message is posted, waits for the thread to be available (might be busy, it has to return control to the event loop first) and then, run the method.

This can be done using signals and slots, with the usual connection. If you don't want to use that mechanism, you can use QMetaObject, but you still have to declare those as slots. The static method invokeMethod, if called with Qt::QueuedConnection will invoke the method in the thread in which the object owning the method is living. You can also pass arguments to the method and returns values from it.

Consider that any data types you want to be able to pass from a thread to another need to be registered with qRegisterMetaType and must respect the conditions reported in there.

OTHER TIPS

Methods of a class will execute in the context of the thread that calls them. If you move a QObject class to a thread (let's refer to it as worker thread), then only methods of that class that are called directly (or indirectly) from the run() method of the worker thread, will execute in the context of the worker thread.

If you want to call methods on that class from some other thread, but still have them run in the context of the worker thread, then you need some way to get a message to the worker thread so it can call the method you want. This is essentially what is achieved by Qt signals and slots when thread boundaries are crossed.

With a lot of extra work, there are two other ways you can do the same thing. First, QThreads have an event loop which is started by default if you don't override run(). You can create custom events that you can post to the event loop which can trigger activity in your class that will execute in the context of the worker thread.

The second way would be to call methods in your class from another thread that modify class fields that the worker thread monitors. You need to be sure that access to any of these fields is synchronized with some mechanism like a mutex.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top