QWaitCondition Class
Die Klasse QWaitCondition bietet eine Bedingungsvariable für die Synchronisierung von Threads. Mehr...
Kopfzeile: | #include <QWaitCondition> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
- Liste aller Mitglieder, einschließlich geerbter Mitglieder
- QWaitCondition ist Teil der Threading-Klassen.
Hinweis: Alle Funktionen in dieser Klasse sind thread-sicher.
Öffentliche Funktionen
QWaitCondition() | |
~QWaitCondition() | |
void | notify_all() |
void | notify_one() |
bool | wait(QMutex *lockedMutex, QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever)) |
bool | wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever)) |
bool | wait(QMutex *lockedMutex, unsigned long time) |
bool | wait(QReadWriteLock *lockedReadWriteLock, unsigned long time) |
void | wakeAll() |
void | wakeOne() |
Detaillierte Beschreibung
QWaitCondition ermöglicht es einem Thread, anderen Threads mitzuteilen, dass eine bestimmte Bedingung erfüllt wurde. Ein oder mehrere Threads können blockieren, während sie darauf warten, dass eine QWaitCondition eine Bedingung mit wakeOne() oder wakeAll() festlegt. Verwenden Sie wakeOne(), um einen zufällig ausgewählten Thread aufzuwecken, oder wakeAll(), um alle Threads aufzuwecken.
Nehmen wir zum Beispiel an, dass wir drei Aufgaben haben, die ausgeführt werden sollen, sobald der Benutzer eine Taste drückt. Jede Aufgabe könnte in einen Thread aufgeteilt werden, von denen jeder einen run()-Körper wie diesen hätte:
forever { mutex.lock(); keyPressed.wait(&mutex); do_something(); mutex.unlock(); }
Hier ist die Variable keyPressed
eine globale Variable vom Typ QWaitCondition.
Ein vierter Thread würde Tastendrücke lesen und die anderen drei Threads jedes Mal aufwecken, wenn er einen empfängt, etwa so:
forever {
getchar();
keyPressed.wakeAll();
}
Die Reihenfolge, in der die drei Threads aufgeweckt werden, ist nicht festgelegt. Wenn einige der Threads noch in do_something()
sind, wenn die Taste gedrückt wird, werden sie nicht aufgeweckt (da sie nicht auf die Bedingungsvariable warten) und die Aufgabe wird für diesen Tastendruck nicht ausgeführt. Dieses Problem kann mit einem Zähler und einem QMutex gelöst werden, um ihn zu schützen. Hier ist zum Beispiel der neue Code für die Worker-Threads:
forever { mutex.lock(); keyPressed.wait(&mutex); ++count; mutex.unlock(); do_something(); mutex.lock(); --count; mutex.unlock(); }
Hier ist der Code für den vierten Thread:
forever { getchar(); mutex.lock(); // Sleep until there are no busy worker threads while (count > 0) { mutex.unlock(); sleep(1); mutex.lock(); } keyPressed.wakeAll(); mutex.unlock(); }
Der Mutex ist notwendig, weil die Ergebnisse von zwei Threads, die gleichzeitig versuchen, den Wert derselben Variablen zu ändern, unvorhersehbar sind.
Wartebedingungen sind ein leistungsfähiges Primitiv für die Thread-Synchronisierung. Das Beispiel Producer and Consumer using Wait Conditions zeigt, wie man QWaitCondition als Alternative zu QSemaphore verwendet, um den Zugriff auf einen Ringpuffer zu steuern, der von einem Producer-Thread und einem Consumer-Thread gemeinsam genutzt wird.
Siehe auch QMutex, QSemaphore, QThread und Producer und Consumer unter Verwendung von Wartebedingungen.
Dokumentation der Mitgliedsfunktionen
QWaitCondition::QWaitCondition()
Konstruiert ein neues Wartebedingungsobjekt.
[noexcept]
QWaitCondition::~QWaitCondition()
Zerstört das Wartebedingungsobjekt.
void QWaitCondition::notify_all()
Diese Funktion ist aus Gründen der STL-Kompatibilität vorgesehen. Sie ist äquivalent zu wakeAll().
void QWaitCondition::notify_one()
Diese Funktion ist aus Gründen der STL-Kompatibilität vorgesehen. Sie ist äquivalent zu wakeOne().
bool QWaitCondition::wait(QMutex *lockedMutex, QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))
Gibt die lockedMutex frei und wartet auf die Wartebedingung. lockedMutex muss zunächst vom aufrufenden Thread gesperrt werden. Wenn lockedMutex sich nicht in einem gesperrten Zustand befindet, ist das Verhalten undefiniert. Wenn lockedMutex eine rekursive Mutex ist, kehrt diese Funktion sofort zurück. lockedMutex wird entsperrt, und der aufrufende Thread blockiert, bis eine dieser Bedingungen erfüllt ist:
- Ein anderer Thread signalisiert es mit wakeOne() oder wakeAll(). In diesem Fall gibt diese Funktion true zurück.
- die in deadline angegebene Frist ist erreicht. Wenn deadline gleich
QDeadlineTimer::Forever
ist (die Vorgabe), wird die Wartezeit nie abgelaufen sein (das Ereignis muss signalisiert werden). Diese Funktion gibt false zurück, wenn die Wartezeit abgelaufen ist.
lockedMutex wird wieder in den gleichen gesperrten Zustand versetzt. Diese Funktion wird bereitgestellt, um den atomaren Übergang vom gesperrten Zustand zum Wartezustand zu ermöglichen.
Siehe auch wakeOne() und wakeAll().
bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))
Gibt die lockedReadWriteLock frei und wartet auf die Wartebedingung. lockedReadWriteLock muss zunächst durch den aufrufenden Thread gesperrt werden. Wenn lockedReadWriteLock nicht gesperrt ist, kehrt diese Funktion sofort zurück. lockedReadWriteLock darf nicht rekursiv gesperrt werden, da diese Funktion sonst die Sperre nicht ordnungsgemäß aufhebt. lockedReadWriteLock wird entsperrt, und der aufrufende Thread blockiert, bis eine der beiden Bedingungen erfüllt ist:
- Ein anderer Thread signalisiert es mit wakeOne() oder wakeAll(). In diesem Fall gibt diese Funktion true zurück.
- die in deadline angegebene Frist ist erreicht. Wenn deadline gleich
QDeadlineTimer::Forever
ist (die Vorgabe), wird die Wartezeit nie abgelaufen sein (das Ereignis muss signalisiert werden). Diese Funktion gibt false zurück, wenn die Wartezeit abgelaufen ist.
lockedReadWriteLock wird in den gleichen gesperrten Zustand zurückversetzt. Diese Funktion wird bereitgestellt, um den atomaren Übergang vom gesperrten Zustand zum Wartezustand zu ermöglichen.
Siehe auch wakeOne() und wakeAll().
bool QWaitCondition::wait(QMutex *lockedMutex, unsigned long time)
Dies ist eine überladene Funktion.
Gibt die lockedMutex frei und wartet auf die Wartebedingung für time Millisekunden.
bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, unsigned long time)
Dies ist eine überladene Funktion.
Gibt die lockedReadWriteLock frei und wartet auf die Wartebedingung für time Millisekunden.
void QWaitCondition::wakeAll()
Weckt alle Threads auf, die auf die Wartebedingung warten. Die Reihenfolge, in der die Threads aufgeweckt werden, hängt von den Planungsrichtlinien des Betriebssystems ab und kann nicht kontrolliert oder vorhergesagt werden.
Siehe auch wakeOne().
void QWaitCondition::wakeOne()
Weckt einen Thread auf, der auf die Wartebedingung wartet. Welcher Thread aufgeweckt wird, hängt von den Planungsrichtlinien des Betriebssystems ab und kann nicht kontrolliert oder vorhergesagt werden.
Wenn Sie einen bestimmten Thread aufwecken wollen, besteht die Lösung normalerweise darin, verschiedene Wartebedingungen zu verwenden und verschiedene Threads auf verschiedene Bedingungen warten zu lassen.
Siehe auch wakeAll().
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.