- •Часть 4. Локальное взаимодействие процессов
- •Глава 16. Блокирование записей 89
- •12.2. Процессы, потоки и общий доступ к информации
- •12.3. Живучесть объектов ipc
- •12.4. Пространства имен
- •12.5. Действие команд fork, exec и exit на объекты ipc
- •12.6. Комментарии к примерам ipc
- •12.7. Выводы по главе 12
- •12.8. Упражнения по главе 12
- •Глава 13. Именованные и неименованные каналы
- •13.1. Введение
- •13.2. Приложение типа клиент-сервер
- •13.3. Программные каналы
- •13.4. Функции popen и pclose
- •13.5. Именованные каналы (fifo)
- •13.6. Некоторые свойства именованных и неименованных каналов
- •13.7. Один сервер, несколько клиентов
- •13.8. Последовательные и параллельные серверы
- •13.9. Ограничения программных каналов и fifo
- •13.10. Выводы по главе 13
- •13.11. Упражнения по главе 13
- •Глава 14. Программные потоки
- •14.1. Введение
- •14.2. Концепция потоков
- •14.3. Идентификация потоков
- •14.4. Создание потока
- •14.5. Завершение потока
- •Функции управления процессами и потоками
- •14.6. Установка атрибутов потока
- •14.7. Реентерабельность
- •Альтернативные версии функций, безопасные в многопоточной среде
- •14.8. Локальные данные потоков
- •14.9. Принудительное завершение потоков
- •Некоторые точки выхода, определенные стандартом Posix.1
- •14.10. Потоки и сигналы
- •14.11. Выводы по главе 14
- •14.12. Упражнения по главе 14 Глава 15. Средства синхронизации потоков
- •15.1. Введение
- •15.2. Взаимные исключения: установка и снятие блокировки
- •15.2.1. Схема производитель-потребитель
- •15.2.2. Блокирование и опрос
- •15.2.3. Предотвращение тупиковых ситуаций
- •15.3. Условные переменные
- •15.3.1. Ожидание и сигнализация
- •15.3.2. Исключение состояния гонок
- •15.4. Блокировки чтения-записи
- •15.5. Атрибуты средств синхронизации потоков
- •15.5.1. Атрибуты взаимных исключений
- •Поведение взаимных исключений различных типов
- •15.5.2. Атрибуты условных переменных
- •15.5.3. Атрибуты блокировок чтения-записи
- •15.6. Выводы по главе 15
- •15.7. Упражнения по главе 15
- •Глава 16. Блокирование записей
- •16.1. Введение
- •16.2. Блокирование записей и файлов
- •16.3. Блокирование записей с помощью fcntl по стандарту Posix
- •16.4. Рекомендательная блокировка
- •16.5. Обязательная блокировка
- •16.6. Приоритет чтения и записи Выводы по главе 16
- •Упражнения по главе 16 Глава 17. System V ipc
- •17.1. Введение
- •17.2. Ключи типа key_t и функция ftok
- •17.3. Структура ipc_perm
- •17.4. Создание и открытие каналов ipc
- •17.5. Разрешения ipc
- •17.6. Программы ipcs и ipcrm
- •17.7. Ограничения ядра
- •17.8. Выводы по главе 17
- •17.9. Упражнения по главе 17
- •Глава 18. Очереди сообщений System V
- •18.1. Введение
- •18.2. Функция msgget
- •18.3. Функция msgsnd
- •18.4. Функция msgrcv
- •18.5. Функция msgctl
- •18.6. Пример программы клиент-сервер
- •18.7. Мультиплексирование сообщений
- •18.7.1. Пример: одна очередь на приложение
- •18.7.2. Пример: одна очередь для каждого клиента
- •18.8. Ограничения, накладываемые на очереди сообщений
- •18.9. Выводы по главе 18
- •18.10. Упражнения по главе 18
- •Глава 19. Семафоры System V
- •19.1. Введение
- •19.2. Функция semget
- •19.3. Функция semop
- •19.4. Функция semctl
- •19. . Ограничения семафоров System V
- •19. . Выводы по главе 19
- •19. . Упражнения по главе 19 Глава 20. Введение в разделяемую память
- •20.1. Введение
- •20.2. Функции mmap, munmap и msync
- •20.3. Увеличение счетчика в отображаемом в память файле
- •20.4. Неименованное отображение в память
- •20.5. Обращение к объектам, отображенным в память
- •20.6. Выводы по главе 20
- •20.7. Упражнения по главе 20
- •Глава 21. Разделяемая память System V
- •21.1. Введение
- •21.2. Функция shmget
- •21.3. Функция shmat
- •21.4. Функция shmdt
- •21.5. Функция shmctl
- •21.6. Ограничения, накладываемые на разделяемую память
- •21.7. Выводы по главе 21
- •21.8. Упражнения по главе 21
13.10. Выводы по главе 13
Программные каналы и FIFO представляют собой базовые строительные блоки для множества приложений. Программные каналы обычно используются в интерпретаторе команд, а также внутри программ – в основном для обмена информацией между родительским и дочерним процессами. Можно исключить часть программного кода, относящегося к использованию каналов (pipe, fork, close, exec и waitpid), используя функции popen и pclose, которые берут на себя все тонкости и запускают интерпретатор команд.
Каналы FIFO похожи на программные каналы, но их создают с помощью функции mkfifo и затем открывают с помощью функции open. При открытии FIFO следует быть аккуратным, поскольку процесс может быть заблокирован, а зависит это от множества условий, перечисленных в табл. 13.1.
Используя программные каналы и FIFO, мы создали несколько вариантов приложений типа клиент-сервер: один сервер с несколькими клиентами, последовательный и параллельный серверы. Последовательный сервер единовременно обрабатывает запрос только от одного клиента; такие серверы обычно уязвимы для атак типа “отказ в обслуживании”. Параллельный сервер запускает отдельный процесс или поток для обработки запроса нового клиента.
Одной из особенностей программных каналов и FIFO является то, что данные по ним передаются в виде потоков байтов, аналогично соединению TCP. Деление этого потока на самостоятельные записи целиком предоставляется приложению. Мы увидим в главе 17, что очереди сообщений автоматически расставляют границы между записями, аналогично тому, как это делается в дейтаграммах UDP.
13.11. Упражнения по главе 13
13.1. Описывая функцию mkfifoв разделе 13.5, мы сказали, что для открытия существующего FIFO или создания нового, если его не существует, следует вызватьmkfifo, проверить, не случилась ли ошибкаEEXIST, и вызватьopen, если произошла эта ошибка. Что произойдет, если изменить логику работы и вызвать сначалаopen, а затемmkfifo, если FIFO не существует?
13.2. Удалите вызов функции open(с флагомO_WRONLY) для FIFO сервера влистинге 13.6и проверьте, приведет ли это к завершению работы сервера после отключения последнего клиента.
13.3. К листингу 13.6: мы отметили, что при запуске сервера его работа блокируется при первом вызове функцииopen(с флагомO_RDONLY) для FIFO сервера, пока этот канал FIFO не будет открыт на запись первым клиентом. Как можно избежать блокирования таким образом, чтобы оба последовательных вызова функцииopenдля FIFO сервера немедленно возвращали управление, а блокирование происходило при первом вызове функцииfgets?
13.4. Что произойдет с клиентом из листинга 13.7, если поменять порядок вызовов функцииopen?
13.5. Почему сигнал SIGPIPEотправляется процессу, в котором канал FIFO открыт на запись (табл. 13.1), после отключения последнего читающего клиента, а не читающему процессу после отключения последнего пишущего клиента?
13.6. Напишите небольшую тестирующую программу для определения того, возвращает ли функция fstatколичество байтов, находящихся в FIFO, в полеst_sizeструктурыstat.
Глава 14. Программные потоки
