EAGAIN
EINVALSEM_VALUE_MAX
EPERM
ENOSPC
ENOSYSsem_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()Функция ожидания с проверкой семафора,
sem_trywait()Функция ожидания с тайм-аутом,
sem_timedwait()abs_timeoutTimerTimeout()SIGEV_UNBLOCKОперации освобождения
int sem_post(sem_t* sem);Эта операция увеличивает на единицу (инкремент) внутренний счетчик семафора, и в этом она диаметрально противоположна операции блокировки. Если перед этим значение счетчика семафора было равно 0, то один из потоков, ожидающих разблокирования семафора, переходит в состояние готовности. Из списка ожидающих потоков система выбирает самый приоритетный, а если таких несколько, то поток, дольше всех ждавший из очереди наиболее приоритетных потоков.
Эта функция имеет свой оригинал в native API QNX:
int SyncSemPost(sync_t* sync);Фактически разница между POSIX и QNX API в вариантах этой функции состоит в регистрируемых ею ошибках.
Функция
sem_post()
EINVALsem;
ENOSYSsem_post()В отличие от
sem_post()SyncSemPost()
EAGAIN
EFAULTsync
EINTR
EINVALsyncКак видим, функция QNX API несколько разнообразнее в плане контроля передаваемых аргументов и результата выполнения функции.
Получение статуса семафора
int sem_getvalue(sem_t* sem, int* value);Эта функция используется преимущественно для отладки операций над семафорами. По адресу, указанному в
valueВозможные ошибки:
EINVALsem.Использование семафора
Как уже говорилось выше, семафор является крайне гибким и эффективным средством синхронизации, особенно удобным для построения собственных средств планирования выполнения потоков. В этом смысле семафор представляет ценность не только как самостоятельное средство синхронизации выполнения потоков, но и как материал для построения специфических средств планирования и синхронизации для конкретных задач. Мы уже говорили, что семафор образует самодостаточный базис, позволяющий строить гораздо более сложные средства синхронизации без привлечения других средств синхронизации. В принципе это так, но нет ничего плохого и в смешанном использовании как семафоров, так и мьютексов для построения собственных средств синхронизации.
Проиллюстрируем все вышесказанное на двух примерах. Сначала мы построим «очередь сообщений», предназначенную для трансляции сообщений графической системы к «медленному» обработчику реакций. Это одно из решений весьма распространенной задачи о предотвращении «зависания» пользовательского интерфейса на период выполнения медленного обработчика. Для решения этой задачи обработчик события оконной системы (например, нажатия кнопки или выбора пункта меню) и функция, которая непосредственно производит требуемые действия (предусмотренные по наступлению указанного события - нажатия кнопки), должны располагаться в разных потоках.