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
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
, устанавливается текущее значение счетчика семафора. Поскольку значение счетчика семафора может измениться в любой момент, то значение, которое возвращает эта функция, имеет смысл только непосредственно в точке ее вызова.
Читать дальше
Конец ознакомительного отрывка
Купить книгу