Spec-Zone.ru › Qt 6.1

Класс QSystemSemaphore

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

Заголовок: #include <QSystemSemaphore>
CMake: find_package(Qt6 COMPONENTS Core REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
  • Список всех членов, включая унаследованные

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

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

Функции публичного доступа

QSystemSemaphore(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Открыто)
~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 = Открыто)

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

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

Как и его более лёгкий аналог 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 автоматически отменяет действие всех операций acquire, которые не были освобождены. Таким образом, если процесс приобретает ресурс, а затем выходит из строя, не освободив его, Unix освободит этот ресурс.

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

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

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

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

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

перечисление 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 = Открыто)

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

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

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

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

Параметр mode используется только в системах Unix, чтобы обработать случай, когда семафор переживает сбой процесса. В этом случае следующий процесс, который выделит семафор с тем же key, получит семафор, переживший сбой, и если mode не Create, счётчик ресурсов не будет сброшен до 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. Если новый key отличается от старого ключа, вызов этой функции аналогичен вызову деструктора семафора со старым ключом, за которым следует вызов конструктора для создания нового семафора с новым key. Параметры initialValue и mode определены так же, как и для конструктора.

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

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

Spec-Zone.ru

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