Spec-Zone.ru › Qt 5.9

Класс QSystemSemaphore

Класс QSystemSemaphore предоставляет общий системный семафор со счётчиком. Подробнее...

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

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

перечисление AccessMode { Open, Create }
перечисление SystemSemaphoreError { NoError, PermissionDenied, KeyError, AlreadyExists, ..., UnknownError }

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

QSystemSemaphore(const QString &key, int initialValue = 0, AccessMode mode = Open)
~QSystemSemaphore()
bool acquire()
SystemSemaphoreError error() const
QString errorString() const
QString key() const
bool release(int n = 1)
void setKey(const QString &key, int initialValue = 0, AccessMode mode = Open)

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

Класс QSystemSemaphore предоставляет общий системный семафор со счётчиком.

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

Подобно своему более лёгкому аналогу QSemaphore, QSystemSemaphore может быть доступен из нескольких потоков. В отличие от QSemaphore, QSystemSemaphore также может быть доступен из нескольких процессов. Это означает, что QSystemSemaphore — это гораздо более тяжёлый класс, поэтому если вашему приложению не нужно обращаться к семафорам через несколько процессов, вы, вероятно, захотите использовать QSemaphore.

Семафоры поддерживают две основные операции: acquire() и release():

acquire() пытается захватить один ресурс. Если ресурс недоступен, вызов блокируется до тех пор, пока ресурс не станет доступным. Затем ресурс захватывается, и вызов возвращается.

release() освобождает один ресурс, чтобы он мог быть захвачен другим процессом. Функция также может вызываться с параметром n > 1, что освобождает n ресурсов.

Системный семафор создаётся с помощью строкового ключа, который другие процессы могут использовать для доступа к тому же семафору.

Пример: Создание системного семафора

QSystemSemaphore sem("market", 3, QSystemSemaphore::Create);
                             // resources available == 3
sem.acquire();               // resources available == 2
sem.acquire();               // resources available == 1
sem.acquire();               // resources available == 0
sem.release();               // resources available == 1
sem.release(2);              // resources available == 3

Типичное применение системных семафоров — управление доступом к кольцевому буферу, совместно используемому процессом-производителем и процессом-потребителем.

Платформенно-специфическое поведение

Используя этот класс, имейте в виду следующие отличия между платформами:

Windows: QSystemSemaphore не владеет своим системным семафором. Владеет им Windows. Это означает, что когда все экземпляры QSystemSemaphore для определённого ключа были уничтожены, либо вызовом их деструкторов, либо из-за падения одного или нескольких процессов, Windows удаляет системный семафор.

Unix:

  • QSystemSemaphore владеет системным семафором в системах Unix. Это означает, что последний процесс, имеющий экземпляр QSystemSemaphore для определённого ключа, должен удалить системный семафор в своём деструкторе. Если последний процесс аварийно завершается, не вызвав деструктор QSystemSemaphore, Unix не удаляет системный семафор автоматически, и семафор сохраняется после аварии. Следующий процесс, который создаёт QSystemSemaphore с тем же ключом, получит существующий системный семафор. В этом случае, если конструктор QSystemSemaphore указал режим доступа access mode как Open, его начальное значение счётчика не будет сброшено до заданного, но останется установленным в то значение, которое он получил в аварийно завершившемся процессе. Чтобы защитить от этого, первый процесс, создающий семафор для определённого ключа (обычно сервер), должен указать access mode как Create, что заставит Unix сбросить значение счётчика в системном семафоре.
  • Когда процесс, использующий QSystemSemaphore, завершается по какой-либо причине, Unix автоматически отменяет действие всех операций захвата, которые не были освобождены. Таким образом, если процесс захватывает ресурс и затем завершается без его освобождения, Unix освободит этот ресурс.

См. также QSharedMemory и QSemaphore.

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

перечисление QSystemSemaphore::AccessMode

Это перечисление используется конструктором и setKey(). Его цель — решить проблему в реализациях семафоров на Unix, которые могут сохраняться после аварии. В Unix, когда семафор сохраняется после аварии, нам нужен способ принудительно сбросить его счётчик ресурсов, когда система повторно использует семафор. В Windows, где семафоры не могут сохраняться после аварии, это перечисление не влияет.

Постоянная Значение Описание
QSystemSemaphore::Open 0 Если семафор уже существует, его начальное значение счётчика не сбрасывается. Если семафора не существует, он создаётся, и его начальное значение счётчика устанавливается.
QSystemSemaphore::Create 1 QSystemSemaphore берёт на себя управление семафором и устанавливает его счётчик ресурсов в запрошенное значение независимо от того, существует ли семафор из-за сохранения после аварии. Это значение должно быть передано в конструктор, когда первый семафор для определённого ключа создаётся, и вы знаете, что если семафор уже существует, это может произойти только из-за аварии. В Windows, где семафор не может сохраниться после аварии, Create и Open имеют одинаковое поведение.

перечисление QSystemSemaphore::SystemSemaphoreError

Постоянная Значение Описание
QSystemSemaphore::NoError 0 Ошибка не произошла.
QSystemSemaphore::PermissionDenied 1 Операция завершилась неудачно, так как у вызывающего процесса не было необходимых разрешений.
QSystemSemaphore::KeyError 2 Операция завершилась неудачно из-за неверного ключа.
QSystemSemaphore::AlreadyExists 3 Операция завершилась неудачно, так как системный семафор с указанным ключом уже существовал.
QSystemSemaphore::NotFound 4 Операция завершилась неудачно, так как системный семафор с указанным ключом не был найден.
QSystemSemaphore::OutOfResources 5 Операция завершилась неудачно из-за нехватки памяти.
QSystemSemaphore::UnknownError 6 Произошла другая ошибка.

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

QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue = 0, AccessMode mode = Open)

Запрашивает системный семафор для указанного key. Параметры initialValue и mode используются в соответствии со следующими правилами, которые зависят от системы.

В Unix, если mode — Open, а системный семафор с заданным key уже существует, используется этот семафор, и значение счётчика семафора не изменяется, т.е. initialValue игнорируется. Но если системного семафора с заданным key не существует, создаётся новый семафор для этого ключа, и устанавливается его счётчик ресурсов в initialValue.

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

В Windows, режим игнорируется, и система всегда пытается создать семафор для указанного ключа. Если в системе ещё нет семафора, идентифицированного как ключ, семафор создаётся, и его счетчик ресурсов устанавливается в начальное значение. Но если семафор с идентификатором ключ уже существует, используется этот семафор, а начальное значение игнорируется.

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

См. также acquire() и key().

QSystemSemaphore::~QSystemSemaphore()

Деструктор уничтожает объект QSystemSemaphore, но подлежащий семафор системы не удаляется из системы, пока этот экземпляр QSystemSemaphore является последним, существующим для этого семафора системы.

Два важных побочных эффекта деструктора зависят от системы. В Windows, если для этого семафора был вызван acquire(), но не вызван release(), release() не будет вызван деструктором, и ресурс не будет освобождён при нормальном завершении процесса. Это будет ошибка программы, которая может стать причиной тупиковой ситуации в другом процессе, пытающемся получить тот же ресурс. В Unix, полученные ресурсы, которые не были освобождены до вызова деструктора, автоматически освобождаются при завершении процесса.

bool QSystemSemaphore::acquire()

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

Если возвращается false, произошла системная ошибка. Вызовите error(), чтобы получить значение QSystemSemaphore::SystemSemaphoreError, которое указывает, какая ошибка произошла.

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

SystemSemaphoreError QSystemSemaphore::error() const

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

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

QString QSystemSemaphore::errorString() const

Возвращает текстовое описание последней произошедшей ошибки. Если error() возвращает значение ошибки, вызовите эту функцию, чтобы получить текстовую строку, описывающую ошибку.

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

QString QSystemSemaphore::key() const

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

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

bool QSystemSemaphore::release(int n = 1)

Освобождает n ресурсов, защищённых семафором. Возвращает true за исключением случаев системных ошибок.

Пример: Создайте семафор системы с пятью ресурсами; получите все из них, а затем освободите все.

QSystemSemaphore sem("market", 5, QSystemSemaphore::Create);
for (int i = 0; i < 5; ++i)  // acquire all 5 resources
    sem.acquire();
sem.release(5);              // release the 5 resources

Эта функция также может «создавать» ресурсы. Например, сразу после последовательности операторов выше, предположим, что мы добавили оператор:

sem.release(10);          // "create" 10 new resources

Теперь семафор защищает десять новых ресурсов в дополнение к уже существующим пяти. Обычно вы не будете использовать эту функцию для создания дополнительных ресурсов.

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

void QSystemSemaphore::setKey(const QString &key, int initialValue = 0, AccessMode mode = Open)

Эта функция работает так же, как конструктор. Она перестраивает этот объект QSystemSemaphore. Если новый ключ отличается от старого ключа, вызов этой функции аналогичен вызову деструктора семафора со старым ключом, а затем вызову конструктора для создания нового семафора с новым ключом. Параметры initialValue и mode определены так же, как и для конструктора.

См. также QSystemSemaphore() и key().

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

Spec-Zone.ru

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