Стивенс Уильям Ричард
Шрифт:
Функция sem_trywait
В листинге 10.43 приведен текст нашей функции sem_trywait, которая представляет собой неблокируемую версию sem_wait.
13 Единственное отличие от функции sem_wait из листинга 10.42 заключается в том, что флагу sem_flg присваивается значение IPC_NOWAIT. Если операция не может быть завершена без блокирования вызвавшего потока, функция semop возвращает ошибку EAGAIN, а это именно тот код, который должен быть возвращен sem_trywait, если операция не может быть завершена без блокирования потока.
Функция sem_getvalue
Последняя функция приведена в листинге 10.44. Это функция sem_getvalue, возвращающая текущее значение семафора.
11-14 Текущее значение семафора получается отправкой команды GETVAL функции semctl.
10.17. Резюме
Семафоры Posix представляют собой семафоры-счетчики, для которых определены три основные операции:
1. Создание семафора.
2. Ожидание изменения значения семафора на ненулевое и последующее уменьшение значения.
3. Увеличение значения семафора на 1 и возобновление выполнения всех процессов, ожидающих его изменения.
Семафоры Posix могут быть именованными или неименованными (размещаемыми в памяти). Именованные семафоры всегда могут использоваться отдельными процессами, тогда как размещаемые в памяти должны для этого изначально планироваться как разделяемые между процессами. Эти типы семафоров также отличаются друг от друга по живучести: именованные семафоры обладают по меньшей мере живучестью ядра, тогда как размещаемые в памяти обладают живучестью процесса.
Задача производителей и потребителей является классическим примером для иллюстрации использования семафоров. В этой главе первое решение состояло из одного потока-производителя и одного потока-потребителя; второе решение имело нескольких производителей и одного потребителя, а последнее решение допускало одновременную работу и нескольких потребителей. Затем мы показали, что классическая задача двойной буферизации является частным случаем задачи производителей и потребителей с одним производителем и одним потребителем.
В этой главе было приведено три примера возможной реализации семафоров Posix. Первый пример был самым простым, в нем использовались каналы FIFO, а большая часть забот по синхронизации ложилась на ядро (функции read и write). Следующая реализация использовала отображение файлов в память (аналогично реализации очередей сообщений Posix из раздела 5.8), а также взаимное исключение и условную переменную (для синхронизации). Последняя реализация была основана на семафорах System V и представляла собой, по сути, удобный интерфейс для работы с ними.