Spec-Zone.ru › Qt 5.13

Класс QSystemSemaphore

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

Заголовок: #include <QSystemSemaphore>
qmake: QT += core
С тех пор: Qt 4.4

Этот класс был представлен в Qt 4.4.

  • Список всех членов, включая унаследованные

Типы публичного доступа

перечисление AccessMode { Открыт, Создать }
перечисление SystemSemaphoreError { НетОшибки, НетДоступа, НеверныйКлюч, УжеСуществует, ..., НеизвестнаяОшибка }

Публичные функции

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

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

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

Как и его более лёгкий аналог 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 указал режим доступа AccessMode как Открыт, его начальное значение счётчика ресурсов не будет сброшено до заданного значения, а останется равным значению, полученному в аварийно завершившем работу процессе. Для защиты от этого первый процесс, создающий семафор для определённого ключа (обычно сервер), должен передать режим доступа AccessMode как Создать, что заставит 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, QSystemSemaphore::AccessMode mode = Open)

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

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

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

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

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

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

QSystemSemaphore::~QSystemSemaphore()

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

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

bool QSystemSemaphore::acquire()

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

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

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

QSystemSemaphore::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, QSystemSemaphore::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.13/qsystemsemaphore.html

Spec-Zone.ru

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