Mir-knigi.online
Книги онлайн читать бесплатно!
  • Главная
  • Жанры
  • ТОП книг
  • ТОП авторов
  • Контакты

Linux программирование в примерах

Часть 126 из 253 Информация о книге

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

Следующая программа,

ch09-pipeline.c
, создает эквивалент следующего конвейера оболочки:

$ <b>echo hi there | sed s/hi/hello/g</b>

hello there

Вот программа:

1  /* ch09-pipeline.c --- ответвляет два процесса в их собственный конвейер.

2     Для краткости проверка ошибок сведена к минимуму. */

3

4  #include &lt;stdio.h&gt;

5  #include &lt;errno.h&gt;

6  #include &lt;sys/types.h&gt;

7  #include &lt;sys/wait.h&gt;

8  #include &lt;unistd.h&gt;

9

10 int pipefd[2];

11

12 extern void left_child(void), right_child(void);

13

14 /* main --- порождение процессов и ожидание их завершения */

15

16 int main(int argc, char **argv)

17 {

18  pid_t left_pid, right_pid;

19  pid_t ret;

20  int status;

21

22  if (pipe(pipefd) &lt; 0) { /* создать канал в самом начале */

23   perror(&quot;pipe&quot;);

24   exit(1);

25  }

26

27  if ((left_pid = fork()) &lt; 0) { /* порождение левого потомка */

28   perror(&quot;fork&quot;);

29   exit(1);

30  } else if (left_pid == 0)

31  left_child();

32

33  if ((right_pid = fork()) &lt; 0) { /* порождение правого потомка */

34   perror(&quot;fork&quot;);

35   exit(1);

36  } else if (right_pid == 0)

37  right_child();

38

39  close(pipefd[0])); /* закрыть родительские копии канала */

40  close(pipefd[1]);

41

42  while ((ret = wait(&amp;status)) &gt; 0) { /* wait for children */

43   if (ret == left_pid)

44    printf(&quot;left child terminated, status: %x\n&quot;, status);

45   else if (ret == right_pid)

46    printf(&quot;right child terminated, status: %x\n&quot;, status);

47   else

48    printf(&quot;yow! unknown child %d terminated, status %x\n&quot;,

49     ret, status);

50  }

51

52  return 0;

53 }

Строки 22–25 создают канал. Это должно быть сделано в самом начале.

Строки 27–31 создают левого потомка, а строки 33–37 создают правого потомка. В обоих случаях родитель продолжает линейное исполнение ветви

main()
до тех пор, пока порожденный процесс не вызовет соответствующую функцию для манипулирования дескрипторами файла и осуществления
exec
.

Строки 39–40 закрывают родительскую копию канала.

Строки 42–50 в цикле ожидают потомков, пока

wait()
не вернет ошибку.

55 /* left_child --- осуществляет работу левого потомка */

56

57 void left_child(void)

58 {

59  static char *left_argv[] = { &quot;echo&quot;, &quot;hi&quot;, &quot;there&quot;, NULL };

60

61  close(pipefd[0]);

62  close(1);

63  dup(pipefd[1]);

64  close(pipefd[1]);

65

66  execvp(&quot;echo&quot;, left_argv);

67  _exit(errno == ENOENT ? 127 : 126);

68 }

69

70 /* right_child --- осуществляет работу правого потомка */

71

72 void right_child(void)

73 {

74  static char *right_argv[] = { &quot;sed&quot;, &quot;s/hi/hello/g&quot;, NULL };

75

76  close(pipefd[1]);

77  close(0);

78  dup(pipefd[0]);

79  close(pipefd[0]));

80

81  execvp(&quot;sed&quot;, right_argv);

82  _exit(errno == ENOENT ? 127 : 126);

83 }

Строки 57–68 являются кодом для левого потомка. Процедура следует приведенным выше шагам, закрывая ненужный конец канала, закрывая первоначальный стандартный вывод, помещая с помощью

dup()
записываемый конец канала на номер 1 и закрывая затем первоначальный записываемый конец. В этот момент строка 66 вызывает
execvp()
, и если она завершается неудачей, строка 67 вызывает
_exit()
. (Помните, что строка 67 никогда не выполняется, если
execvp()
завершается удачно.)


Перейти к странице:
Предыдущая страница
Следующая страница
Жанры
  • Военное дело
  • Деловая литература
  • Детективы и триллеры
  • Детские
  • Детские книги
  • Документальная литература
  • Дом и дача
  • Дом и Семья
  • Жанр не определен
  • Зарубежная литература
  • Знания и навыки
  • История
  • Компьютеры и Интернет
  • Легкое чтение
  • Любовные романы
  • Научно-образовательная
  • Образование
  • Поэзия и драматургия
  • Приключения
  • Проза
  • Прочее
  • Психология и мотивация
  • Публицистика и периодические издания
  • Религия и духовность
  • Родителям
  • Серьезное чтение
  • Спорт, здоровье и красота
  • Справочная литература
  • Старинная литература
  • Техника
  • Фантастика и фентези
  • Фольклор
  • Хобби и досуг
  • Юмор
Mir-knigi.online

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

Контакты
  • [email protected]
Информация
  • Карта сайта
© mir-knigi.online, 2026. | Вход