Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Qt signals/slots with non-Qt threads

I've done my due diligence but can't find an answer to this one:

How does the Qt signal/slot mechanism interact with non-Qt threads?

In particular, is it safe to emit a signal from a non-Qt (e.g. TBB) thread, to be caught by a slot in my main event loop? Supposing I connect it with a queued connection explicitly? (My feeling is that specifying that the connection is queued would be mandatory; is this correct?)

(As a side question, I have been assuming that in general, the Qt synchronization classes, e.g. QMutex, work across non-Qt threads. Is this correct?)

(As a clarifying remark, the thing that I'm worried about is that the queued connection mechanism will not use guards, e.g. mutexes, to add the metacall to the main thread event queue if it does not detect that the signal is being emitted from a different Qt thread.)

(Final addition: I can believe that because the Qt mechanisms are implemented in terms of platform-specific primitives, that in practice all of the things that I am trying to do will just work gracefully, but I'm also wondering if Qt provides any guarantees that these things will work.)

like image 277
Andrey Mishchenko Avatar asked Jan 14 '15 16:01

Andrey Mishchenko


People also ask

Are Qt signals and slots thread safe?

It is generally unsafe to provide slots in your QThread subclass, unless you protect the member variables with a mutex. On the other hand, you can safely emit signals from your QThread::run() implementation, because signal emission is thread-safe.

How do I connect Qt signals and slots?

There are several ways to connect signal and slots. The first is to use function pointers: connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed); There are several advantages to using QObject::connect() with function pointers.

What is emit in Qt?

emit is just syntactic sugar. If you look at the pre-processed output of function that emits a signal, you'll see emit is just gone. The "magic" happens in the generated code for the signal emitting function, which you can look at by inspecting the C++ code generated by moc.

What are Qt Public slots?

In C++, public means those members that are accessible from anywhere where the object is visible, private means that members are accessible only from within other members of the same class or from their friends. But in Qt, the difference in private slots and public slots seem not to exist.


Video Answer


1 Answers

The documentation states:

Note: Qt's threading classes are implemented with native threading APIs; e.g., Win32 and pthreads. Therefore, they can be used with threads of the same native API.

So yes, Qt's mutexes will work with other threads (as long as they also use the same native API).

The difference between Qt threads and other threads is that other threads will never have Qt's event loop running, so won't be able to receive and handle any signals. However, if you'll run the event loop (exec) inside such a thread everything should work fine.

The signal related functions, mainly processEvents and postEvent are said to be thread safe:

Note: This function is thread-safe.

If the objects have the thread affinity set correctly (using the moveToThread method) you don't need to set the connection type explicitly, the default AutoConnection works as follows:

(default) If the signal is emitted in the thread which the receiving object has affinity then the behavior is the same as the Direct Connection. Otherwise, the behavior is the same as the Queued Connection.

This answer suggests that non-Qt threads should also be correctly identifiable by Qt's methods - currentThread should return a QThread instance even for a non-Qt thread, as it's only a wrapper over native threads.

like image 180
BartoszKP Avatar answered Oct 19 '22 13:10

BartoszKP