Spec-Zone.ru › Qt 5.14

Класс QSystemSemaphore

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

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

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

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

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

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

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

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

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

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

В Unix, если mode равен Create и система уже имеет семафор с идентификатором 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-5.14/qsystemsemaphore.html

Spec-Zone.ru

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