Книга: Программирование для Linux. Профессиональный подход
Листинг 5.7. (pipe.c) Общение с дочерним процессом посредством канала
Листинг 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, "%sn", 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".
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Что делать, если при установке принтера появляется сообщение Невозможно завершение операции. Подсистема печати недоступн...
- При копировании с жесткого диска на «флэшку» иногда появляется сообщение о дополнительной присоединенной информации, кот...
- Сообщение канала
- 5.12.2 Открытие поименованного канала
- Листинг 15.11. Код для загрузки файла с Web-сервера
- Метасообщение
- При входе в систему появляется сообщение о невозможности найти какой-то файл. Как его убрать?
- При подключении к локальной сети компьютер выдает сообщение об ошибке «В сети существуют совпадающие имена». Что делать?
- Вот уже в который раз при работе в сети появляется сообщение от других пользователей. Что это может быть?
- При загрузке Windows появляется сообщение – неправильный файл boot. ini. За что этот файл отвечает и как исправить данну...
- При установке драйвера появляется сообщение об отсутствии у драйвера цифровой подписи