Класс QMutexLocker
Класс QMutexLocker — это вспомогательный класс, который упрощает блокировку и разблокировку мьютексов. Подробнее...
| Заголовок: | #include <QMutexLocker> |
| qmake: | QT += core |
Примечание: Все функции в этом классе являются безопасными для потоков.
Открытые функции
| QMutexLocker(QRecursiveMutex *mutex) | |
| QMutexLocker(QMutex *mutex) | |
| ~QMutexLocker() | |
| QMutex * | mutex() const |
| void | relock() |
| void | unlock() |
Подробное описание
Блокировка и разблокировка QMutex в сложных функциях и операторах или в коде обработки исключений подвержена ошибкам и затрудняет отладку. QMutexLocker может использоваться в таких ситуациях, чтобы гарантировать, что состояние мьютекса всегда определено.
QMutexLocker должен быть создан внутри функции, где требуется блокировка QMutex. Мьютекс блокируется при создании QMutexLocker. Вы можете разблокировать и повторно заблокировать мьютекс с помощью unlock() и relock(). Если он заблокирован, мьютекс будет разблокирован при уничтожении QMutexLocker.
Например, эта сложная функция блокирует QMutex при входе в функцию и разблокирует мьютекс во всех точках выхода:
int complexFunction(int flag)
{
mutex.lock();
int retVal = 0;
switch (flag) {
case 0:
case 1:
retVal = moreComplexFunction(flag);
break;
case 2:
{
int status = anotherFunction();
if (status < 0) {
mutex.unlock();
return -2;
}
retVal = status + flag;
}
break;
default:
if (flag > 10) {
mutex.unlock();
return -1;
}
break;
}
mutex.unlock();
return retVal;
} Эта функция при дальнейшем развитии станет более сложной, что увеличивает вероятность возникновения ошибок.
Использование QMutexLocker значительно упрощает код и делает его более читабельным:
int complexFunction(int flag)
{
QMutexLocker locker(&mutex);
int retVal = 0;
switch (flag) {
case 0:
case 1:
return moreComplexFunction(flag);
case 2:
{
int status = anotherFunction();
if (status < 0)
return -2;
retVal = status + flag;
}
break;
default:
if (flag > 10)
return -1;
break;
}
return retVal;
} Теперь мьютекс всегда будет разблокирован при уничтожении объекта QMutexLocker (при возвращении из функции, так как locker — это автоматическая переменная).
Тот же принцип относится к коду, который генерирует и обрабатывает исключения. Исключение, которое не обрабатывается в функции, заблокировавшей мьютекс, не может разблокировать мьютекс, прежде чем исключение будет передано по стеку вызывающей функции.
QMutexLocker также предоставляет функцию-член mutex(), которая возвращает мьютекс, на котором работает QMutexLocker. Это полезно для кода, которому требуется доступ к мьютексу, например, QWaitCondition::wait(). Например:
class SignalWaiter
{
private:
QMutexLocker locker;
public:
SignalWaiter(QMutex *mutex)
: locker(mutex)
{
}
void waitForSignal()
{
...
while (!signalled)
waitCondition.wait(locker.mutex());
...
}
}; См. также QReadLocker, QWriteLocker и QMutex.
Документация по функциям-членам
QMutexLocker::QMutexLocker(QRecursiveMutex *mutex)
Создает QMutexLocker и блокирует mutex. Мьютекс будет разблокирован (unlock() вызывается) при уничтожении QMutexLocker. Если mutex — nullptr, QMutexLocker ничего не делает.
Эта функция была добавлена в Qt 5.14.
См. также QMutex::lock().
QMutexLocker::QMutexLocker(QMutex *mutex)
Создает QMutexLocker и блокирует mutex. Мьютекс будет разблокирован при уничтожении QMutexLocker. Если mutex — nullptr, QMutexLocker ничего не делает.
См. также QMutex::lock().
QMutexLocker::~QMutexLocker()
Уничтожает QMutexLocker и разблокирует мьютекс, который был заблокирован в конструкторе.
См. также QMutex::unlock().
QMutex *QMutexLocker::mutex() const
Возвращает мьютекс, на котором работает QMutexLocker.
void QMutexLocker::relock()
Повторно блокирует разблокированный мьютекс-локер.
См. также unlock().
void QMutexLocker::unlock()
Разблокирует этот мьютекс-локер. Вы можете использовать relock() для его повторной блокировки. Он не должен быть заблокирован при уничтожении.
См. также relock().
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/qmutexlocker.html