Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:
Упражнение 13.6. Каналы через вызов
fork

1. Это пример pipe2.c. Он выполняется также как первый до того момента, пока вы не вызовете функцию

fork
.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main {

 int data_processed;

 int file_pipes[2];

 const char some_data[] = "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 == -1) {

fprintf(stderr, "Fork failure");

exit(EXIT_FAILURE);

}

2. Вы убедились, что вызов

fork
отработал, поэтому, если его результат равен нулю, вы находитесь в дочернем процессе:

if (fork_result == 0) {

data_processed = read(file_pipes[0], buffer, BUFSIZ);

printf("Read %d bytes: %s\n", data_processed, buffer);

exit(EXIT_SUCCESS);

}

3. В противном случае вы должны быть в родительском процессе:

else {

data_processed = write(file_pipes[1], some_data,

strlen(some_data));

printf("Wrote %d bytes\n", data_processed);

}

 }

 exit(EXIT_SUCCESS);

}

После выполнения этой программы вы получите вывод, аналогичный предыдущему:

$ ./pipe2

Wrote 3 bytes

Read 3 bytes: 123

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

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

Сначала программа создает канал с помощью вызова

pipe
. Далее она применяет вызов
fork
для создания нового процесса. Если
fork
завершился успешно, родительский процесс пишет данные в канал, в то время как дочерний считывает данные из канала. Оба процесса, и родительский, и дочерний, завершаются после одного вызова
write
и
read
. Если родительский процесс завершается раньше дочернего, вы можете увидеть между двумя выводами строку приглашения командной оболочки.

Несмотря на то, что программа внешне похожа на первый пример

pipe
, мы сделали большой шаг вперед, получив возможность использовать разные процессы для чтения и записи (рис. 13.2).

Рис. 13.2 

Родительский и дочерний процессы

Следующий логический шаг в нашем изучении вызова

pipe
— разрешить дочернему процессу быть другой программой, отличной от своего родителя, а не просто другим процессом, выполняющим ту же самую программу. Сделать это можно с помощью вызова
exec
. Единственная сложность заключается в том, что новому процессу, созданному
exec
, нужно знать, какой файловый дескриптор применять для доступа. В предыдущем примере этой проблемы не возникло, потому что дочерний процесс обращался к своей копии данных
file_pipes
. После вызова
exec
возникает другая ситуация, поскольку старый процесс заменен новым дочерним процессом. Эту проблему можно обойти, если передать файловый дескриптор (который, в конце концов, просто число) как параметр программе, вновь созданной с помощью вызова
exec
.

Для того чтобы посмотреть, как это работает, вам понадобятся две программы (упражнение 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>

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

Точка Бифуркации VIII

Смит Дейлор
8. ТБ
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации VIII

Глэрд VIII: Базис 2

Владимиров Денис
8. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Глэрд VIII: Базис 2

Воронцов. Перезагрузка. Книга 2

Тарасов Ник
2. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Воронцов. Перезагрузка. Книга 2

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Шайтан Иван 5

Тен Эдуард
5. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
5.00
рейтинг книги
Шайтан Иван 5

Московское золото или нежная попа комсомолки. Часть Вторая

Хренов Алексей
2. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото или нежная попа комсомолки. Часть Вторая

Ищу жену с прицепом

Рам Янка
2. Спасатели
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Ищу жену с прицепом

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14

Дракон - не подарок

Суббота Светлана
2. Королевская академия Драко
Фантастика:
фэнтези
6.74
рейтинг книги
Дракон - не подарок

Бальмануг. (Не) Любовница 2

Лашина Полина
4. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Бальмануг. (Не) Любовница 2

Бандит

Щепетнов Евгений Владимирович
1. Петр Синельников
Фантастика:
фэнтези
7.92
рейтинг книги
Бандит

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Кодекс Охотника. Книга XV

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Барон отрицает правила

Ренгач Евгений
13. Закон сильного
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Барон отрицает правила