Вход/Регистрация
Основы программирования в Linux
вернуться

Мэтью Нейл

Шрифт:

Для того чтобы посмотреть, как это работает, вам понадобятся две программы (упражнение 13.7). Первая — поставщик данных. Она создает канал и затем вызывает дочерний процесс, потребитель данных.

Упражнение 13.7. Каналы и
exec

1. Для получения первой программы исправьте pipe2.c, превратив ее в pipe3.c. Измененные строки затенены.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main {

 int data_processed;

 int file_pipes[2];

 const char somedata[] = "123";

 char buffer[BUFSIZ + 1];

 pid_t fork_result;

 memset(buffer, '\0', sizeof(buffer));

 if (pipe(file_pipes) == 0) {

fork_result = fork;

if (fork_result == (pid_t)-1) {

fprintf(stderr, "Fork failure");

exit(EXIT_FAILURE);

}

if (fork_result == 0) {

sprintf(buffer, "%d", file_pipes[0]);

(void)execl("pipe4", "pipe4", buffer, (char*)0);

exit(EXIT_FAILURE);

} else {

data_processed = write(file_pipes[1], some_data, strlen(some_data));

printf ("%d - wrote %d bytes\n", getpid, data_processed);

}

 }

 exit(EXIT_SUCCESS);

}

2. Программа-потребитель pipe4.c, читающая данные, гораздо проще:

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main(int argc, char *argv[]) {

 int data_processed;

 char buffer[BUFSIZ + 1];

 int file_descriptor;

 memset(buffer, '\0', sizeof(buffer));

 sscanf(argv[1], "%d", &file_descriptor);

 data_processed = read(file_descriptor, buffer, BUFSIZ);

 printf("%d — read %d bytes: %s\n", getpid, data_processed,

buffer);

 exit(EXIT_SUCCESS);

}

Выполнив pipe3 и помня о том, что она вызывает программу pipe4, вы получите вывод, аналогичный приведенному далее:

$ ./pipe3

22460 - wrote 3 bytes

22461 - read 3 bytes: 123

Как это работает

Программа pipe3 начинается как предыдущий пример, используя вызов

pipe
для создания канала и затем вызов
fork
для создания нового процесса. Далее она применяет функцию
sprintf
для сохранения в буфере номера файлового дескриптора чтения из канала, который формирует аргумент программы pipe4.

Вызов

execl
применен для вызова программы pipe4. В нем использованы следующие аргументы:

 вызванная программа;

 

argv[0]
, принимающий имя программы;

 

argv[1]
, содержащий номер файлового дескриптора, из которого программа должна читать;

 

(char *)0
, завершающий список параметров.

Программа pipe4 извлекает номер файлового дескриптора из строки аргументов и затем читает из него данные.

Чтение закрытых каналов

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

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

  • Читать дальше
  • 1
  • ...
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: