КаталогИндекс раздела
НазадОглавлениеВперед


      

Лабораторная работа N3

Цель работы: освоение неименованных программных каналов как способа обмена данными между процессами.

Каналы - общее сведения

Программный канал в Unix/Linux представляет собой одно из средств взаимодействия между процессами. Само название (pipe, дословно - трубка) достаточно точно передает смысл функционирования этого средства. Канал подобен трубопроводу, проложенному между двумя процессами, и по этому трубопроводу процессы могут пересылать друг другу данные. Подобно трубопроводу, канал имеет собственную емкость, данные, направленные в канал процессом-отправителем, не обязательно должны быть немедленно прочитаны процессом-получателем, но могут накапливаться в канале. Как и у трудобровода, емкость канала конечна, когда она будет исчерпана, запись в канал становится невозможной.

Операционные системы Unix/Linux представляеют в распоряжение программистов два вида каналов - именованные и неименованные. Работа с обоими видами во многом подобна работе с файлами.

Неименованные каналы

Неименованный канал является средством взаимодействия между связанными процессами - родительским и дочерним. Родительский процесс создает канал при помощи системного вызова:

    int pipe(int fd[2]);

Массив из двух целых чисел является выходным параметром этого системного вызова. Если вызов выполнился нормально, то этот массив содержит два файловых дескриптора. fd[0] является дескриптором для чтения из канала, fd[1] - дескриптором для записи в канал. Когда процесс порождает другой процесс, дескрипторы родительского процесса наследуются дочерним процессом, и, таким образом, прокладывается трубопровод между двумя процессами. Естественно, что один из процессов использует канал только для чтения, а другой - только для записи (сами представьте себе, что произойдет, если это правило будет нарушаться). Поэтому, если, например, через канал должны передаваться данные из родительского процесса в дочерний, родительский процесс сразу после запуска дочернего процесса закрывает дескриптор канала для чтения, а дочерний процесс закрывает дескриптор для записи. Если нужен двунаправленный обмен данными между процессами, то родительский процесс создает два канала, один из которых используется для передачи данных в одну сторону, а другой - в другую. После получения процессами дескрипторов канала для работы с каналом используются файловые системные вызовы:

   int read(int pipe_fd, void *area, int cnt);
   int write(int pipe_fd, void *area, int cnt);

Первый аргумент этих вызовов - дескриптор канала, второй - указатель на область памяти, с которой происходит обмен, третий - количество байт. Оба вызова возвращают число переданных байт (или -1 - при ошибке).

Выполнение этих системных вызовов может переводить процесс в состояние ожидания. Это происходит, если процесс пытается читать данные из пустого канала или писать данные в переполненный канал. Процесс выходит из ожидания, когда в канале появляются данные или когда в канале появляется свободное место, соответственно.

При завершении использования канала процесс выполняет системный вызов:

   int close(int pipe_fd);

Если родительский процесс, создавший канал, порождает несколько дочерних процессов, то все дочерние процессы подключены к другому концу канала. Если, например, родительский процесс выводит данные в канал, то они "достанутся" тому дочернему процессу, который раньше выполнит системный вызов read.

Постановка задачи

Для заданной в Вашем варианте индивидуального задания предметной области разработайте программную модель ситуации, включающей в себя следующее:

Отчет по лабораторной работе

Отчет по лабораторной работе должен содержать:

Пример выполнения работы N3 приведен здесь.


Назад ОглавлениеВперед
КаталогИндекс раздела