Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Интернет » Linux программирование в примерах - Роббинс Арнольд

Linux программирование в примерах - Роббинс Арнольд

Читать онлайн Linux программирование в примерах - Роббинс Арнольд

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 147 148 149 150 151 152 153 154 155 ... 253
Перейти на страницу:

Строки 99–100 создают набор сигналов, представляющих SIGCHLD, а строка 102 устанавливает их в качестве маски сигналов процесса для программы.

Строки 104–109 создают пять порожденных процессов, каждый из которых засыпает на три секунды. По ходу дела они обновляют массив kids и переменную nkids.

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

Наконец, строки 113–114 выводят сообщение и приостанавливаются, заменив маску сигналов процесса, блокирующую SIGCHLD, пустой маской. Это дает возможность появиться сигналу SIGCHLD, что в свою очередь вызывает запуск обработчика сигнала. Вот что происходит:

$ <b>ch10-reap1</b> /* Запуск программы */

waiting for signal

Entered childhandler

  reaped process 23937

  reaped process 23938

  reaped process 23939

  reaped process 23940

  reaped process 23941

Exited childhandler

Обработчик сигнала собирает сведения о потомках за один проход.

Следующая программа, ch10-reap2.c, сходна с ch10-reap1.c. Разница в том, что она допускает появление сигнала SIGCHLD в любое время. Такое поведение увеличивает шанс получения более одного SIGCHLD, но не гарантирует это. В результате обработчик сигнала все равно должен быть готов обработать в цикле несколько потомков.

1  /* ch10-reap2.c — демонстрирует управление SIGCHLD, один сигнал на потомка */

2

   /* ...не изменившийся код пропущен... */

12

13 pid_t kids[MAX_KIDS];

14 size_t nkids = 0;

15 size_t kidsleft = 0; /* &lt;&lt;&lt; Добавлено */

16

 /* ...не изменившийся код пропущен... */

41

42 /* childhandler --- перехват SIGCHLD, опрос всех доступных потомков */

43

44 void childhandler(int sig)

45 {

46  int status, ret;

47  int i;

48  char buf[100];

49  static const char entered[] = &quot;Entered childhandlern&quot;;

50  static const char exited[] = &quot;Exited childhandlern&quot;;

51

52  write(1, entered, strlen(entered));

53  for (i = 0; i &lt; nkids; i++) {

54   if (kids[i] == NOT_USED)

55    continue;

56

57 retry:

58  if ((ret = waitpid(kids[i], &amp;status, WNOHANG)) == kids[i]) {

59   strcpy(buf, &quot;treaped process &quot;);

60   strcat(buf, format_num(ret));

61   strcat(buf, &quot;n&quot;);

62   write(1, buf, strlen(buf));

63   kids[i] = NOT_USED;

64   kidsleft--; /* &lt;&lt;&lt; Добавлено */

65  } else if (ret == 0) {

    /* ...не изменившийся код пропущен... */

80  write(1, exited, strlen(exited));

81 }

Это идентично предыдущей версии за тем исключением, что у нас есть новая переменная, kidsleft, указывающая, сколько имеется не опрошенных потомков. Строки 15 и 64 помечают новый код.

83  /* main --- установка относящейся к порожденным процессам сведений

       и сигналов, создание порожденных процессов */

84

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

86  {

     /* ...не изменившийся код пропущен... */

100

101  sigemptyset(&amp;childset);

102  sigaddset(&amp;childset, SIGCHLD);

103

104  /* sigprocmask(SIG_SETMASK, &amp;childset, NULL); /* блокирование в коде main */

105

106  for (nkids = 0; nkids &lt; 5; nkids++) {

107   if ((kids[nkids] = fork()) == 0) {

108    sleep(3);

109    _exit(0);

110   }

111   kidsleft++; /* &lt;&lt;&lt; Added */

112  }

113

114  /* sleep(5); /* дать потомкам шанс завершиться */

115

116  while (kidsleft &gt; 0) { /* &lt;&lt;&lt; Добавлено */

117   printf(&quot;waiting for signalsn&quot;);

118   sigsuspend(&amp;emptyset);

119  } /* &lt;&lt;&lt; Добавлено */

120

121  return 0;

122 }

Здесь код также почти идентичен. Строки 104 и 114 закомментированы из предыдущей версии, а строки 111, 116 и 119 добавлены. Удивительно, при запуске поведение меняется в зависимости от версии ядра!

$ <b>uname -a</b> /* Отобразить версию системы */

Linux example1 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux

1 ... 147 148 149 150 151 152 153 154 155 ... 253
Перейти на страницу:
Тут вы можете бесплатно читать книгу Linux программирование в примерах - Роббинс Арнольд.
Комментарии