Qt Signal Slot Thread Safety

Posted on by admin
  1. Qt Signal Slot Thread Safety Chart
  2. Qt Connect Signal Slot
  3. Qt Signal Slot Thread Safety Device
  4. Qt Signal Slot
Home All Classes Main Classes Annotated Grouped Classes Functions

As mentioned, each program has one thread when it is started. This thread is called the 'main thread' (also known as the 'GUI thread' in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. Qt Signal Slot Thread Safe Get £1000 bonus + bonus spins at Viks Casino! Register and deposit at Viks Casino to receive 3 deposit bonuses, worth a total of £1000 + 50 bonus spins!

Qt provides thread support in the form of basic platform-independentthreading classes, a thread-safe way of posting events, and a globalQt library lock that allows you to call Qt methods from differentthreads.

  • This might sound somewhat uninteresting at first, but it means you can have your own signals and slots outside the main thread. The Trolls created a new way to connect signals to slots such that signals can actually cross thread boundaries. I can now emit a signal in one thread and receive it in a slot in a different thread.
  • The Qt signals/slots and property system are based on the ability to introspect the objects at runtime. Introspection means being able to list the methods and properties of an object and have all kinds of information about them such as the type of their arguments. QtScript and QML would have hardly been possible without that ability.

This document is intended for an audience that has knowledge andexperience with multithreaded applications. Recommended reading:

Qt Signal Slot Thread Safety Chart

Enabling Thread Support

When Qt is installed on Windows, thread support is an option on somecompilers.

On Mac OS X and Unix, thread support is enabled by adding the-thread option when running the configure script. On Unixplatforms where multithreaded programs must be linked in special ways,such as with a special libc, installation will create a separatelibrary, libqt-mt and hence threaded programs must be linkedagainst this library (with -lqt-mt) rather than the standard Qtlibrary.

On both platforms, you should compile with the macro QT_THREAD_SUPPORT defined (e.g. compile with-DQT_THREAD_SUPPORT). On Windows, this is usually done by anentry in qconfig.h.

The Thread Classes

These classes are built into the Qt library when thread support is enabled:

  • QThread - Provides the means to start a new thread, which beginsexecution in your reimplementation of QThread::run(). This is similarto the Java thread class.
  • QMutex - Provides a mutual exclusion lock (also know as a mutex).
  • QMutexLocker - A convenience class which automatically locks andunlocks a QMutex. QMutexLocker is useful in complicated code, or incode which uses exceptions. See the documentation for more details.
  • QWaitCondition - Provides a way for threads to go to sleep untilwoken up by another thread.
  • QSemaphore - Provides a simple integer semaphore.

Qt Connect Signal Slot

Important Information

When using Qt in a multithreaded program, it is important tounderstand the definition of the terms reentrant and thread-safe:

  • reentrant - Describes a function which can be calledsimultaneously by multiple threads when each invocation of thefunction references unique data. Calling a reentrant functionsimultaneously with the same data is not safe, and such invocationsshould be serialized.
  • thread-safe - Describes a function which can be calledsimultaneously by multiple threads when each invocation referencesshared data. Calling a thread-safe function simultaneously with thesame data is safe, since all access to the shared data are serialized.

Most C++ member functions are inherently reentrant, since they onlyreference class member data. Any thread can call such a memberfunction on an instance, as long as no other thread is calling amember function on the same instance. For example, given the class Number below:

The methods Number::number() and Number::setNumber() arereentrant, since they only reference unique data. Only one thread ata time can call member functions on each instance of Number.However, multiple threads can call member functions on separateinstances of Number.

Qt signal slot thread safety chart

Thread-safe functions usually use a mutex (e.g a QMutex) to serializeaccess to shared data. Because of this, thread-safe functions areusually slower than reentrant functions, because of the extra overheadof locking and unlocking the mutex. For example, given the class Counter below:

Since the modifications of the static instances integer are notserialized, this class is not thread-safe. So make it threadsafe, amutex must be used:

Thread-safe Event Posting

In Qt, one thread is always the GUI or event thread. This is thethread that creates a QApplication object and callsQApplication::exec(). This is also the initial thread that callsmain() at program start. This thread is the only thread that isallowed to perform GUI operations, including generating and receivingevents from the window system. Qt does not support creatingQApplication and running the event loop (with QApplication::exec()) ina secondary thread. You must create the QApplication object and callQApplication::exec() from the main() function in your program.

Threads that wish to display data in a widget cannot modify the widgetdirectly, so they must post an event to the widget usingQApplication::postEvent(). The event will be delivered later on bythe GUI thread.

Normally, the programmer would like to include some information in theevent sent to the widget. See the documentation for QCustomEvent formore information on user-defined events.

Threads and QObject

The QObject class itself is reentrant. However, certain rulesapply when creating and using QObjects in a thread that is not the GUIthread.

  1. None of the QObject based classes included in the Qt library arereentrant. This includes all widgets (e.g. QWidget andsubclasses), OS kernel classes (e.g. QProcess, QAccel, QTimer), andall networking classes (e.g. QSocket, QDns).
  2. QObject and all of its subclasses are notthread-safe. Thisincludes the entire event delivery system. It is important toremember that the GUI thread may be delivering events to your QObjectsubclass while you are accessing the object from another thread. Ifyou are using QObject in a thread that is not the GUI thread, and youare handling events sent to this object, you must protect allaccess to your data with a mutex; otherwise you may experience crashesor other undesired behavior.
  3. As a corollary to the above, deleting a QObject while pendingevents are waiting to be delivered can cause a crash. You must notdelete the QObject directly from a thread that is not the GUI thread.Use the QObject::deleteLater() method instead, which will cause theevent loop to delete the object after all pending events have beendelivered to the object.

The Qt Library Mutex

QApplication includes a mutex that is used to protect access to windowsystem functions. This mutex is locked while the event loop isrunning (e.g. during event delivery) and unlocked when the eventloopgoes to sleep. Note: The Qt event loop is recursive, and the librarymutex is not unlocked when re-entering the event loop (e.g. whenexecuting a modal dialog with QDialog::exec()).

If another thread locks the Qt library mutex, then the event loop willstop processing events, and the locking thread may do simple GUIoperations. Operations such as creating a QPainter and drawing a lineare examples of simple GUI operations:

Any operations that generate events must not be called by any threadother than the GUI thread. Examples of such operations are:

  • creating a QWidget, QTimer, QSocketNotifier, QSocket or other network class.
  • moving, resizing, showing or hiding a QWidget.
  • starting or stoping a QTimer.
  • enabling or disabling a QSocketNotifier.
  • using a QSocket or other network class.

Events generated by these operations will be lost on some platforms.

Threads and Signals and Slots

Qt Signal Slot Thread Safety Device

The Signals and Slots mechanism can be used in separate threads, aslong as the rules for QObject based classes are followed. The Signalsand Slots mechanism is synchronous: when a signal is emitted, allslots are called immediately. The slots are executed in the threadcontext that emitted the signal.

Warning: Slots that generate window system events or use window systemfunctions mustnot be connected to a signal that is emitted froma thread that is not the GUI thread. See the Qt Library Mutex sectionabove for more details.

Threads and Shared Data

Qt provides many implicitly shared and explicitly shared classes. Ina multithreaded program, multiple instances of a shared class canreference shared data, which is dangerous if one or more threadsattempt to modify the data. Qt provides the QDeepCopy class, whichensures that shared classes reference unique data. See thedocumentation for more details.

Threads and the SQL Module

The classes in the SQL Module can be used in separate threads, as longas the rules for QObject based classes are followed.

The 3rd party libraries used by the QSqlDrivers can impose otherrestrictions on using the SQL Module in a multithreaded program. Forexample, the PostgreSQL library requires a separate connection perthread. Consult the documentation for your 3rd party library for moreinformation.

Caveats

Some things to watch out for when programming with threads:

  • As mentioned above, QObject based classes are neither thread-safenor reentrant. This includes all widgets (e.g. QWidget andsubclasses), OS kernel classes (e.g. QProcess, QAccel), and allnetworking classes (e.g. QSocket, QDns).
  • Deleting a QObject while pending events are waiting to be deliveredwill cause a crash. If you are creating QObjects in a thread that isnot the GUI thread and posting events to these objects, you should notdelete the QObject directly. Use the QObject::deleteLater() methodinstead, which will cause the event loop to delete the object afterall pending events have been delivered to the object.
  • Don't do any blocking operations while holding the Qt librarymutex. This will freeze up the event loop.
  • Make sure you unlock a recursive QMutex as many times as you lockit, no more and no less.
  • Don't mix the normal Qt library and the threaded Qt library in yourapplication. This means that if your application uses the threaded Qtlibrary, you should not link with the normal Qt library, dynamicallyload the normal Qt library or dynamically load another library orplugin that depends on the normal Qt library. On some systems, doingthis can corrupt the static data used in the Qt library.
  • Qt does not support creating QApplication and running the eventloop (with QApplication::exec()) in a secondary thread. You mustcreate the QApplication object and call QApplication::exec() from themain() function in your program.

Qt Signal Slot

Copyright © 2003TrolltechTrademarks