5.4.2. Взаимодействие родительского и дочернего процессов

5.4.2. Взаимодействие родительского и дочернего процессов

Функция pipe() создает два файловых дескриптора, которые действительны только в текущем процессе и его потомках. Эти дескрипторы нельзя передать постороннему процессу. Дочерний процесс получает копии дескрипторов после завершения функции fork().

В программе, показанной в листинге 5.7. родительский процесс записывает в канал строку, а дочерний процесс читает ее. С помощью функции fdopen() файловые дескрипторы приводятся к типу FILE*. Благодаря этому появляется возможность использовать высокоуровневые функции ввода-вывода, такие как printf() и fgets().

Листинг 5.7. (pipe.c) Общение с дочерним процессом посредством канала

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

/* Запись указанного числа копий (COUNT) сообщения (MESSAGE)

   в поток (STREAM) с паузой между каждой операцией. */

void writer(const char* message, int count, FILE* stream) {

 for (; count > 0; --count) {

 /* Запись сообщения в поток с немедленным "выталкиванием"

    из буфера. */

 fprintf(stream, "%s ", message);

 fflush(stream);

 /* Небольшая пауза. */

 sleep(1);

}

/* Чтение строк из потока, пока он не опустеет. */

void reader(FILE* stream) {

 char buffer[1024];

 /* Чтение данных, пока не будет обнаружен конец потока.

    Функция fgets() завершается, когда встречает символ

    новой строки или признак конца файла. */

 while (!feof(stream)

  && !ferror(stream)

  && fgets(buffer, sizeof (buffer), stream) != NULL)

  fputs(buffer, stdout);

}

int main() {

 int fds[2];

 pid_t pid;

 /* Создание канала. Дескрипторы обоих концов канала

    помещаются в массив FDS. */

 pipe(fds);

 /* порождение дочернего процесса. */

 pid = fork();

 if (pid == (pid_t)0) {

  FILE* stream;

  /* Это дочерний процесс. Закрываем копию входного конца

     канала. */

  close(fds[1]);

  /* Приводим дескриптор выходного конца канала к типу FILE*

     и читаем данные из канала. */

  stream = fdopen(fds[0], "r");

  reader(stream);

  close(fds[0]);

 } else {

  /* Это родительский процесс. */

  FILE* stream;

  /* Закрываем копию выходного конца канала. */

  close(fds[0]);

  /* Приводим дескриптор входного конца канала к типу FILE*

     и записываем данные в канал. */

  stream = fdopen(fds[1], "w");

  writer("Hello, world.", 5, stream);

  close(fds[1]);

 }

 return 0;

}

Сначала в программе объявляется массив fds, состоящий из двух целых чисел. Функция pipe() создает канал и помещает в массив дескрипторы входного и выходного концов канала. Затем функция fork() порождает дочерний процесс. После закрытия выходного конца канала родительский процесс начинает записывать строки в канал. Дочерний процесс читает строки из канала, предварительно закрыв его входной конец.

Обратите внимание на то. что в функции writer() родительский процесс принудительно "выталкивает" буфер канала, вызывая функцию fflush(). Без этого строка могла бы ""застрять" в буфере и отправиться в канал только после завершения родительского процесса.

При вызове команды ls | less функция fork() выполняется дважды: один раз — для дочернего процесса ls, второй раз — для дочернего процесса less. Оба процесса наследуют копии дескрипторов канала, поэтому могут общаться друг с другом. О соединении несвязанных процессов речь пойдет ниже, в разделе 5.4.5, "Каналы FIFO".

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

ГЛАВА 11. ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

ГЛАВА 11. ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ Наличие механизмов взаимодействия дает произвольным процессам возможность осуществлять обмен данными и синхронизировать свое выполнение с другими процессами. Мы уже рассмотрели несколько форм взаимодействия процессов, такие как


11.2 ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ В ВЕРСИИ V СИСТЕМЫ

Из книги Компьютер на 100. Начинаем с Windows Vista автора Зозуля Юрий

11.2 ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ В ВЕРСИИ V СИСТЕМЫ Пакет IPC (interprocess communication) в версии V системы UNIX включает в себя три механизма. Механизм сообщений дает процессам возможность посылать другим процессам потоки сформатированных данных, механизм разделения памяти позволяет


Практическая работа 60. Настройка родительского контроля

Из книги Практика и проблематика моделирования бизнес-процессов автора Всяких Е И

Практическая работа 60. Настройка родительского контроля Задание. Настроить ограничения при использовании компьютера детьми и проверить их работу. ВНИМАНИЕ Это задание можно выполнить только в версиях Windows Vista Home Basic, Home Premium и Ultimate и только при использовании учетной


8.15. Вызов виртуальной функции родительского класса

Из книги Программирование КПК и смартфонов на .NET Compact Framework автора Климов Александр П.

8.15. Вызов виртуальной функции родительского класса ПроблемаТребуется вызвать функцию родительского класса, но она переопределена в производном классе, так что обычный синтаксис p->method() не дает нужного результата.РешениеУкажите полное имя вызываемого метода, включая


Отображение дочернего окна

Из книги Linux: Полное руководство автора Колисниченко Денис Николаевич

Отображение дочернего окна Программа должна получить имя игрока при достижении им высокого результата. Для этого создается копия формы HighScore. Программа должна создать форму при старте и хранить ссылку на нее. Экземпляр формы HighScore создается при старте основной


3.3. Взаимодействие процессов

Из книги QNX/UNIX [Анатомия параллелизма] автора Цилюрик Олег Иванович

3.3. Взаимодействие процессов Из всех средств межпроцессного взаимодействия, которыми так богаты UNIX-подобные ОС, в этой главе мы рассмотрим только конвейеры и


Глава 26 Взаимодействие процессов в Linux

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

Глава 26 Взаимодействие процессов в Linux 26.1. Способы взаимодействия Процессы, как и люди, могут «общаться» между собой, то есть обмениваться информацией. В главе 3 мы бегло рассмотрели два средства межпроцессного взаимодействия (IPC, Inter-Process Communication); полудуплексные каналы


Пример кода родительского процесса

Из книги Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil автора Ковязин Алексей Николаевич

Пример кода родительского процесса #include <stdio.h>#include <stdlib.h>#include <string.h>#include <process.h>#include <sys/neutrino.h>#include <sys/netmgr.h>#include <spawn.h>#include <errno.h>#include <unistd.h>#include <sys/wait.h>#include <locale.h>int main(int argc, char **argv) { int nid;     // Дескриптор удаленного узла int PChanid; //


Взаимодействие ограничений

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Взаимодействие ограничений Комбинируя формальное ссылочное ограничение с другими ограничениями целостности (см. главу 16), можно реализовать большинство (если не все) бизнес-правил с высокой степенью точности. Например, ограничение столбца NOT NULL будет корректировать


Эффективное взаимодействие процессов архитектуры Classic Server

Из книги Операционная система UNIX автора Робачевский Андрей М.

Эффективное взаимодействие процессов архитектуры Classic Server В архитектуре Classic Server несколько серверных процессов совместно работают с одной базой данных, осуществляя координацию своих действий через разделяемую таблицу блокировок. Взаимодействие процессов на версиях


Глава 12 Настройка родительского контроля

Из книги автора

Глава 12 Настройка родительского контроля 12.1. Ограничения по времени12.2. Игры12.3. Разрешение и блокировка конкретных программВпервые с понятием родительского контроля пользователи столкнулись в операционной системе Windows Vista. Задумка достаточно интересная: вы можете


Взаимодействие

Из книги автора

Взаимодействие Уведомите свою группу и начальство о неприятностях. Изложите свой план по выходу из кризиса. Обратитесь к ним за информацией и советом. Избегайте сюрпризов. Ничто не сердит людей и не делает их менее рациональными так, как сюрпризы. Сюрпризы повышают