Question

I searched this site and QT documentation, but could not find and direct answer for the following question:

Lets say I have a worker class with only one slot:

void Worker::testSlot(){
  //access data and do some calculation
}

Now if this slot is connected to signal from other classes running on other thread, and if queued connection is used, is it necessary to use lock (QMutexLocker) before accessing data in worker? I think it is not needed since the testSlot() is executed in one thread always (the thread in which worker is moved), and thus it is synchronized. Even if two signals were emitted from different thread at the same time, there is no way to suspend executing the slot in half-way for the first signal and start for second signal. But I am not sure about this.

Was it helpful?

Solution

You're 100% correct.

The key bit of information is that emission of a signal connected to an object in a different thread via a queued or automatic connection results in posting a QMetaCallEvent to the target object. It doesn't directly result in any calls at all.

The event loop running in the thread where the target object resides has toy deliver the event to the object - you can verify that by properly overriding the event method and outputting a debug message when the event has the MetaCall type. Remember to call the base class's method in your reimplementation. Since the event loop runs synchronously, it executes the calls serially. Thus no additional serialization-of-access means are necessary. It doesn't matter what thread the meta call event was posted from - the thread per se is not used for the posting, and the event queue will look the same whether a number of events was posted from one thread, or multiple threads.

It is the QObject::event method that handles the QMetaCallEvent and executes the call. The call may be to a slot, an invokable method, a constructor/destructor, or a functor that is to execute in a given object's thread context.

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