QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович
EAGAIN— в данный момент нет ресурсов для инициализации семафора;
EINVAL— начальное значение счетчика превышает SEM_VALUE_MAX;
EPERM— у процесса недостаточно привилегий для инициализации семафора;
ENOSPC— ресурсы, необходимые для инициализации, исчерпаны;
ENOSYS— функция sem_init()не поддерживается реализацией системы.
При вызове функции sem_destroy()может регистрироваться только одна ошибка:
EINVAL— неправильный описатель семафора.
sem_open()и sem_close()— открытие и закрытие именованного семафора (если отсутствует ранее созданный семафор с таким именем, то его создание). В вопросе подключения и отключения работа с именованным семафором аналогична работе с обычным файлом. Также для именованных семафоров существует операция sem_unlink(), аналогичная операции unlink()для обычного файла. В функцию sem_open()передается имя семафора, параметры открытия семафора и дополнительные параметры в случае создания семафора.
Операции блокировки
Для семафора определены три модификации операции блокировки:
int sem_wait(sem_t* sem);
int sem_trywait(sem_t* sem);
#include <time.h>
int sem_timedwait(sem_t* sem, const struct timespec * abs_timeout);
Все эти функции опираются на функцию (native QNX API):
int SyncSemWait(sync_t* sync, int try);
Функция простого ожидания sem_wait()пытается выполнить декремент счетчика семафора. Если исходное значение счетчика было больше или равно 1, то функция после выполнения операции декремента возвращает управление в вызвавший код. Если же значение внутреннего счетчика семафора равнялось 0, выполнение вызвавшего функцию потока блокируется до тех пор, пока какой-либо другой поток не увеличит значение счетчика семафора. После того как значение счетчика будет увеличено, блокированный поток получает управление (в порядке очереди), выполняет (завершает) декремент счетчика семафора и возвращает управление. Блокированное состояние потока может быть также прервано получением направленного ему сигнала (см. главу 3).
Функция ожидания с проверкой семафора, sem_trywait(), до выполнения операции над семафором проверяет значение счетчика. Если это значение больше нуля, функция выполняет декремент счетчика, а если значение равно нулю - возвращает управление потоку, не блокируясь на ожидании доступности семафора (но захват семафора в этом случае не происходит, о чем извещает код возврата).
Функция ожидания с тайм-аутом, sem_timedwait(), ожидает возможности уменьшить на 1 счетчик семафора (блокируется на ожидании) до момента времени abs_timeout. Это ожидание реализовано с помощью функции TimerTimeout()(native QNX API) с параметром SIGEV_UNBLOCK. Благодаря этой функции может быть прерван ряд состояний блокировки потоков (в том числе блокировки на семафоре, мьютексе и условной переменной).
Операции освобождения
int sem_post(sem_t* sem);
Эта операция увеличивает на единицу (инкремент) внутренний счетчик семафора, и в этом она диаметрально противоположна операции блокировки. Если перед этим значение счетчика семафора было равно 0, то один из потоков, ожидающих разблокирования семафора, переходит в состояние готовности. Из списка ожидающих потоков система выбирает самый приоритетный, а если таких несколько, то поток, дольше всех ждавший из очереди наиболее приоритетных потоков.
Эта функция имеет свой оригинал в native API QNX:
int SyncSemPost(sync_t* sync);
Фактически разница между POSIX и QNX API в вариантах этой функции состоит в регистрируемых ею ошибках.
Функция sem_post()сообщает о следующих ошибках:
EINVAL— неверный дескриптор семафора sem;
ENOSYS— функция sem_post()не поддерживается системой.
В отличие от sem_post(), функция SyncSemPost()может указывать на ошибки:
EAGAIN— недостаточно памяти для создания внутреннего объекта синхронизации;
EFAULT— неверный указатель на семафор sync;
EINTR— выполнение функции прервано сигналом;
EINVAL— аргумент syncне указывает на инициированный семафор.
Как видим, функция QNX API несколько разнообразнее в плане контроля передаваемых аргументов и результата выполнения функции.
Получение статуса семафора
int sem_getvalue(sem_t* sem, int* value);
Эта функция используется преимущественно для отладки операций над семафорами. По адресу, указанному в value, устанавливается текущее значение счетчика семафора. Поскольку значение счетчика семафора может измениться в любой момент, то значение, которое возвращает эта функция, имеет смысл только непосредственно в точке ее вызова.
Возможные ошибки:
EINVAL— неправильный объект семафор sem.
Использование семафора
Как уже говорилось выше, семафор является крайне гибким и эффективным средством синхронизации, особенно удобным для построения собственных средств планирования выполнения потоков. В этом смысле семафор представляет ценность не только как самостоятельное средство синхронизации выполнения потоков, но и как материал для построения специфических средств планирования и синхронизации для конкретных задач. Мы уже говорили, что семафор образует самодостаточный базис, позволяющий строить гораздо более сложные средства синхронизации без привлечения других средств синхронизации. В принципе это так, но нет ничего плохого и в смешанном использовании как семафоров, так и мьютексов для построения собственных средств синхронизации.
Проиллюстрируем все вышесказанное на двух примерах. Сначала мы построим «очередь сообщений», предназначенную для трансляции сообщений графической системы к «медленному» обработчику реакций. Это одно из решений весьма распространенной задачи о предотвращении «зависания» пользовательского интерфейса на период выполнения медленного обработчика. Для решения этой задачи обработчик события оконной системы (например, нажатия кнопки или выбора пункта меню) и функция, которая непосредственно производит требуемые действия (предусмотренные по наступлению указанного события - нажатия кнопки), должны располагаться в разных потоках.
Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович, относящееся к жанру Интернет. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.


