Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учеб.пос.СП.doc
Скачиваний:
28
Добавлен:
31.03.2015
Размер:
1.33 Mб
Скачать

Литература

  1. Глас Г., Эйблс К. Unix для программистов и пользователей. / Г. Глас, К. Эйблс – СПб.: БХВ-Петербург, 2004. – 848 с.: ил.

  2. Брюс М. Unix/Linux: Теория и практика программирования. / М.Брюс - Издательство "Кудиц-Образ", 2004. -576 с.

  3. Роберт Лав. Разработка ядра Linux. / Лав Роберт. - Издательство: Вильямс, 2008. – 448 с.

  4. Собель М.Г. Linux. Администрирование и системное программирование. / М.Г. Собель. - Издательство: Питер, 2011. – 880 с.

Глава 6.Механизмы взаимодействия процессов

До сих пор рассматривалась возможность взаимодействия двух процессов с помощью неименованных каналов. Такого рода взаимодействия возможны только между родительскими и дочерними процессами, при условии, что перед запуском дочернего процесса канал уже был создан, так как передать файловый дескриптор от процесса к процессу можно только через механизм наследования. Это ограничение сильно сужает область применения неименованных каналов. Нужна еще большая гибкость, еще большая управляемость и эффективность.

Современные UNIX-системы помимо неименованных каналов, предоставляет еще целый ряд механизмов взаимодействия процессов. Среди них именованные каналы, очереди сообщений, семафоры, блокировка файлов, общая память и сокеты.

    1. Именованные каналы (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 может оказаться заблокированным.