Qt provides thread support in the form of platform-independent threading classes, a thread-safe way of posting events, and signal-slot connections across threads. This makes it easy to develop portable multithreaded Qt applications and take advantage of multiprocessor machines. Qt - SigSlot - Boost Libraries Qt was the original signal/slots implementation, but it Sigslot and Boost on the other hand are pure ISO C, but both have some disadvantages. None of these are thread-safe and it can be somewhat inconvenient manually Qt documentation states that signals and slots can be direct, queued and auto. Qt Slot Thread Safe that I implement every time I play on an online casino where you play with Qt Slot Thread Safeyour real money first when claiming a bonus. The goal of this strategy is Qt Slot Thread Safeto win a huge amount of. Qt basics: QObjects, signals and slots, event handling; what a thread is and what the relationships are between threads, processes and the operating system; how to start and stop a thread, and wait for it to finish, under (at least) one major operating system; how to use mutexes, semaphores and wait conditions to create thread-safe/reentrant. However, the connected slot function Syncro::jumpToFrame(int newframe) does not get called. If I change the connect from QueuedConnection to DirectConnection the slot function gets called but, as expected, in the context of my serviceThread. I need the slot function to run on the main thread.
Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |
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 document is intended for an audience that has knowledge andexperience with multithreaded applications. Recommended reading:
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.
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.
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.
- 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).
- 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.
- 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.
Qt Slots Thread Safe Vs
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:
Qt Slots Thread Safe List
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.
Qt Thread Signal Slot
Events generated by these operations will be lost on some platforms.
Threads and Signals and Slots
Qt Public Slots
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:
- 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.
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.
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.
- 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).
- 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.
- 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.
Qt Slots Thread Safe Vs
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:
Qt Slots Thread Safe List
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.
Qt Thread Signal Slot
Events generated by these operations will be lost on some platforms.
Threads and Signals and Slots
Qt Public Slots
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.
Copyright © 2003Trolltech | Trademarks |