Spec-Zone.ru › Qt 5.13

Класс QMutex

Класс QMutex обеспечивает сериализацию доступа между потоками. Подробнее...

Заголовок: #include <QMutex>
qmake: QT += core
Наследует: QBasicMutex
  • Список всех членов, включая унаследованные

Примечание: Все функции в этом классе являются потокобезопасными.

Открытые типы

перечисление RecursionMode { Recursive, NonRecursive }

Открытые функции

QMutex(QMutex::RecursionMode mode = NonRecursive)
~QMutex()
bool isRecursive() const
void lock()
bool tryLock(int timeout = 0)
bool try_lock()
bool try_lock_for(std::chrono::duration<Rep, Period> duration)
bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
void unlock()

Подробное описание

Класс QMutex предназначен для защиты объекта, структуры данных или раздела кода, чтобы к нему мог получить доступ только один поток одновременно (это аналогично ключевому слову Java synchronized). Обычно лучше использовать мьютекс с QMutexLocker, так как это упрощает обеспечение последовательного выполнения блокировки и разблокировки.

Например, предположим, что есть метод, который выводит сообщение пользователю на две строки:

int number = 6;

void method1()
{
    number *= 5;
    number /= 4;
}

void method2()
{
    number *= 3;
    number /= 2;
}

Если эти два метода вызываются последовательно, происходит следующее:

// method1()
number *= 5;        // number is now 30
number /= 4;        // number is now 7

// method2()
number *= 3;        // number is now 21
number /= 2;        // number is now 10

Если эти два метода вызываются одновременно из двух потоков, может получиться такая последовательность:

// Thread 1 calls method1()
number *= 5;        // number is now 30

// Thread 2 calls method2().
//
// Most likely Thread 1 has been put to sleep by the operating
// system to allow Thread 2 to run.
number *= 3;        // number is now 90
number /= 2;        // number is now 45

// Thread 1 finishes executing.
number /= 4;        // number is now 11, instead of 10

Если мы добавим мьютекс, мы должны получить нужный результат:

QMutex mutex;
int number = 6;

void method1()
{
    mutex.lock();
    number *= 5;
    number /= 4;
    mutex.unlock();
}

void method2()
{
    mutex.lock();
    number *= 3;
    number /= 2;
    mutex.unlock();
}

Тогда только один поток может изменять number в любой момент времени, и результат будет корректным. Это, конечно, тривиальный пример, но он применим к любому другому случаю, когда действия должны происходить в определенной последовательности.

Когда в потоке вызывается lock(), другие потоки, пытающиеся вызвать lock() в том же месте, будут блокироваться, пока поток, получивший блокировку, не вызовет unlock(). Неблокирующая альтернатива lock() — это tryLock().

QMutex оптимизирован для быстродействия в случае отсутствия конфликтов. Нерекурсивный QMutex не будет выделять память, если нет конфликтов по этому мьютексу. Он создаётся и уничтожается почти без накладных расходов, что означает, что можно иметь множество мьютексов в составе других классов.

См. также QMutexLocker, QReadWriteLock, QSemaphore и QWaitCondition.

Документация по типам членов

перечисление QMutex::RecursionMode

Постоянная Значение Описание
QMutex::Recursive 1 В этом режиме поток может многократно блокировать один и тот же мьютекс, и мьютекс не будет разблокирован, пока не будет выполнено соответствующее количество вызовов unlock().
QMutex::NonRecursive 0 В этом режиме поток может заблокировать мьютекс только один раз.

См. также QMutex().

Документация по функциям-членам

QMutex::QMutex(QMutex::RecursionMode mode = NonRecursive)

Создает новый мьютекс. Мьютекс создается в разблокированном состоянии.

Если mode равен QMutex::Recursive, поток может многократно блокировать один и тот же мьютекс, и мьютекс не будет разблокирован, пока не будет выполнено соответствующее количество вызовов unlock(). В противном случае поток может заблокировать мьютекс только один раз. По умолчанию используется QMutex::NonRecursive.

Рекурсивные мьютексы медленнее и требуют больше памяти, чем нерекурсивные.

См. также lock() и unlock().

QMutex::~QMutex()

Уничтожает мьютекс.

Предупреждение: Уничтожение заблокированного мьютекса может привести к неопределенному поведению.

bool QMutex::isRecursive() const

Возвращает true, если мьютекс рекурсивный.

Эта функция была добавлена в Qt 5.7.

void QMutex::lock()

Захватывает мьютекс. Если другой поток заблокировал мьютекс, этот вызов будет заблокирован до тех пор, пока этот поток не разблокирует его.

Вызов этой функции несколько раз на одном мьютексе из одного потока разрешен, если этот мьютекс является рекурсивным мьютексом. Если этот мьютекс является нерекурсивным мьютексом, эта функция вызовет тупик при рекурсивной блокировке мьютекса.

См. также unlock().

bool QMutex::tryLock(int timeout = 0)

Попытка захватить мьютекс. Эта функция возвращает true, если блокировка была получена; в противном случае возвращает false. Если другой поток заблокировал мьютекс, эта функция будет ждать не более timeout миллисекунд, пока мьютекс не станет доступным.

Примечание: Передача отрицательного числа в качестве timeout эквивалентна вызову lock(), т. е. эта функция будет ждать вечно, пока мьютекс не будет заблокирован, если timeout отрицателен.

Если блокировка была получена, мьютекс необходимо разблокировать с помощью unlock() перед тем, как другой поток сможет успешно заблокировать его.

Вызов этой функции несколько раз на одном мьютексе из одного потока разрешен, если этот мьютекс является рекурсивным мьютексом. Если этот мьютекс является нерекурсивным мьютексом, эта функция всегда вернет false при попытке рекурсивной блокировки мьютекса.

См. также lock() и unlock().

bool QMutex::try_lock()

Попытка захватить мьютекс. Эта функция возвращает true если блокировка была получена; в противном случае возвращает false.

Эта функция предоставляется для совместимости с концепцией Стандартной библиотеки Lockable. Она эквивалентна tryLock().

Функция возвращает true если блокировка была получена; в противном случае возвращает false

Эта функция была добавлена в Qt 5.8.

bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)

Попытка захватить мьютекс. Эта функция возвращает true если блокировка была получена; в противном случае возвращает false. Если другой поток заблокировал мьютекс, эта функция будет ждать как минимум duration, пока мьютекс не станет доступным.

Примечание: Передача отрицательной продолжительности в качестве duration эквивалентна вызову try_lock(). Это поведение отличается от tryLock().

Если блокировка была получена, мьютекс необходимо разблокировать с помощью unlock() перед тем, как другой поток сможет успешно заблокировать его.

Вызов этой функции несколько раз на одном мьютексе из одного потока разрешен, если этот мьютекс является рекурсивным мьютексом. Если этот мьютекс является нерекурсивным мьютексом, эта функция всегда вернет false при попытке рекурсивной блокировки мьютекса.

Эта функция была добавлена в Qt 5.8.

См. также lock() и unlock().

bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)

Попытка захватить мьютекс. Эта функция возвращает true если блокировка была получена; в противном случае возвращает false. Если другой поток заблокировал мьютекс, эта функция будет ждать до timePoint, пока мьютекс не станет доступным.

Примечание: Передача timePoint, который уже прошел, эквивалентна вызову try_lock(). Это поведение отличается от tryLock().

Если блокировка была получена, мьютекс необходимо разблокировать с помощью unlock() перед тем, как другой поток сможет успешно заблокировать его.

Вызов этой функции несколько раз для одного и того же мьютекса в одном и том же потоке разрешен, если этот мьютекс является рекурсивным мьютексом. Если этот мьютекс является нерекурсивным мьютексом, эта функция всегда вернёт false при попытке рекурсивной блокировки мьютекса.

Эта функция была добавлена в Qt 5.8.

См. также lock() и unlock().

void QMutex::unlock()

Разблокирует мьютекс. Попытка разблокировать мьютекс в другом потоке, нежели тот, который его заблокировал, приведёт к ошибке. Разблокировка мьютекса, который не заблокирован, приведёт к неопределённому поведению.

См. также lock().

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/qmutex.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API