
- •Введение
- •Глава 1. Фундаментальные концепции unix Систем
- •Программы, процессы и потоки
- •Сигналы
- •Идентификаторы процессов, группы процессов и сеансы
- •Система прав
- •Другие атрибуты процесса
- •Межпроцессное взаимодействие
- •Использование системных вызовов
- •Краткие описания функций и обработка ошибок
- •Контрольные вопросы
- •Литература
- •Глава 2. Базовые операции ввода-вывода
- •Файловые операции ввода - вывода
- •Стандартные дескрипторы
- •Системные вызовы open и creat
- •Системный вызов umask
- •Системный вызов unlink
- •Текущая позиция в файле
- •Системный вызов write
- •2.8. Системный вызов read
- •2.9. Системный вызов close
- •2.10. Системный вызов lseek
- •2.11. Системные вызовы pread и pwrite
- •2.12. Системные вызовы truncate и ftruncate
- •Контрольные вопросы
- •Литература
- •Глава 3. Дополнительные операции файлового ввода_вывода
- •Низкоуровневый доступ к файловой системе
- •Жесткие и символические ссылки
- •Системный вызов getcwd
- •Отображение метаданных файла
- •Системные вызовы getpwuid, getgrgid и getlogin
- •Каталоги
- •Системные вызовы chdir и fchdir
- •Системные вызовы mkdir и rmdir
- •Контрольные вопросы
- •Литература
- •Глава 4. Процессы и потоки
- •4.1. Среда окружения
- •Системный вызов exec
- •Системный вызов fork
- •Завершение процесса и системные вызовы exit
- •Системные вызовы wait, waitpid и waitid
- •Получение и изменение идентификаторов пользователя и группы
- •Получение и изменение приоритета
- •Контрольные вопросы
- •Литература
- •Глава 5. Механизмы межпроцессного взаимодействия
- •5.1. Каналы
- •5.2. Системные вызовы dup и dup2
- •5.3. Двунаправленное взаимодействие с использованием однонаправленных каналов
- •Контрольные вопросы
- •Литература
- •Глава 6.Механизмы взаимодействия процессов
- •Именованные каналы (fifo)
- •Системные вызовы для работы с очередями сообщений posix
- •Семафоры
- •Системные вызовы для работы с общей памятью posix
- •Контрольные вопросы
- •Литература
- •Глава 7.Сетевое взаимодействие и сокеты
- •Основные системные вызовы для работы с сокетами, образующими логические соединения
- •Обслуживание нескольких клиентов
- •Адресация сокетов
- •In_port_t sin_port; /* номер порта (uint16_t) */
- •In_addr_t s_addr; /* адрес iPv4 (uint32_t) */
- •Домен адресов af_inet6
- •In_port_t sin6_port; /* номер порта (uint16_t) */
- •Доменная система именования
- •Параметры сокетов
- •Контрольные вопросы
- •Литература
- •Глава 8.Сигналы и таймеры
- •Введение в сигналы
- •Жизненный цикл сигналов
- •Типы сигналов
- •Системный вызов sigaction
- •Контрольные вопросы
- •Литература
- •Заключение
- •Список литературы
- •Глава 2. Базовые операции ввода-вывода 14
- •Глава 3. Дополнительные операции файлового ввода_вывода 25
- •Глава 6. Механизмы взаимодействия процессов 58
Литература
Глас Г., Эйблс К. Unix для программистов и пользователей. / Г. Глас, К. Эйблс – СПб.: БХВ-Петербург, 2004. – 848 с.: ил.
Брюс М. Unix/Linux: Теория и практика программирования. / М.Брюс - Издательство "Кудиц-Образ", 2004. -576 с.
Роберт Лав. Разработка ядра Linux. / Лав Роберт. - Издательство: Вильямс, 2008. – 448 с.
Собель М.Г. Linux. Администрирование и системное программирование. / М.Г. Собель. - Издательство: Питер, 2011. – 880 с.
Глава 6.Механизмы взаимодействия процессов
До сих пор рассматривалась возможность взаимодействия двух процессов с помощью неименованных каналов. Такого рода взаимодействия возможны только между родительскими и дочерними процессами, при условии, что перед запуском дочернего процесса канал уже был создан, так как передать файловый дескриптор от процесса к процессу можно только через механизм наследования. Это ограничение сильно сужает область применения неименованных каналов. Нужна еще большая гибкость, еще большая управляемость и эффективность.
Современные UNIX-системы помимо неименованных каналов, предоставляет еще целый ряд механизмов взаимодействия процессов. Среди них именованные каналы, очереди сообщений, семафоры, блокировка файлов, общая память и сокеты.
Именованные каналы (fifo)
Именованные каналы сочетают в себе свойства неименованных каналов и обычных файлов. Подобно файлам, они имеют имя. Любой процесс, наделенный соответствующими правами, сможет открыть его на запись или на чтение. В отличие от неименованных каналов, доступ к FIFO может получить любой процесс, поскольку здесь не требуется наследование дескрипторов. При открытии FIFO на чтение, системный вызов open блокируется до тех пор, пока с другой стороны канал не будет открыт для записи, обычно другим процессом. То же самое происходит и при открытии именованного канала на запись - вызов open блокируется до тех пор, пока с другой стороны канал не будет открыт на чтение. Таким образом, процесс, открывший именованный канал первым, будет вынужден ожидать другой процесс. Это позволяет синхронизировать процессы перед началом передачи данных по каналу.
Если открытие FIFO производится с флагом O_NONBLOCK, вызов open, открывающий канал на чтение, сразу же вернет управление в вызывающую программу с открытым файловым дескриптором. В случае открытия именованного канала на запись с флагом O_NONBLOCK при отсутствии процесса открывшего канал на чтение, вызов open вернет значение -1 и код ошибки ENXIO в переменной errno. Это означает, что флаг O_NONBLOCK больше подходит для открытия FIFO на чтение, чем на запись, иначе придется обыгрывать ошибочную ситуацию и, возможно, повторно запускать системный вызов open. Цель такого асимметричного поведения состоит в том, чтобы предотвратить запись данных в канал, если нет процесса, который был бы готов принять их, потому что в UNIX не предусмотрена возможность постоянного хранения данных в FIFO. Если к моменту закрытия всех дескрипторов в канале остаются какие-либо данные, они будут безвозвратно утеряны.
Создание именованного канала невозможно выполнить с помощью системного вызова open, для этого должен использоваться отдельный вызов:
mkfifo - создает именованный канал
#include <sys/stat.h>
int mkfifo (
const char *path, /* полное имя канала */
mode_t perms /* права доступа */
);
/* Возвращает 0 в случае успеха, -1 в случае ошибки (код ошибки - в errno) */
Аргумент perms используется аналогично третьему аргументу вызова open - он определяет права доступа к каналу. Вместо обращения к pipe создается FIFO и открываются два файловых дескриптора - на чтение и на запись. После этого можно работать с ним как с простым неименованным каналом. Однако именованные каналы, используемые таким образом, не имеют никаких преимуществ перед неименованными каналами (для получения дескрипторов нужно дважды обращаться к системным вызовам).
Именованные каналы добавлены для обеспечения возможности взаимодействия серверных и клиентских процессов. Учитывая, что любой процесс, обладающий соответствующими правами, может открыть FIFO, серверный процесс может создать FIFO с фиксированным именем, к которому будут подключаться клиенты.
Достоинства именованных каналов:
просты в понимании и использовании, потому что по своей природе являются обычными каналами и для работы с ними используются системные вызовы базовых операций ввода-вывода;
доступны в любой версии UNIX;
достаточно эффективны;
хорошо работают как с потоками данных, так и с отдельными сообщениями. Для повышения скорости обмена, читающий процесс может считывать из канала сразу порцию сообщений за раз, а пишущий процесс может записывать данные большими порциями.
Недостатки именованных каналов:
из одного канала может читать только кто-то один, одновременное сосуществование нескольких читателей не допускается;
копирование данных из пространства пользователя одного процесса в пространство ядра и обратно в пространство пользователя другого процесса - очень дорогостоящая операция;
если размер сообщения слишком велик, вызов write может оказаться заблокированным.