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

Роббинс Арнольд

Шрифт:

Строки 99–100 создают набор сигналов, представляющих

SIGCHLD
, а строка 102 устанавливает их в качестве маски сигналов процесса для программы.

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

kids
и переменную
nkids
.

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

Наконец, строки 113–114 выводят сообщение и приостанавливаются, заменив маску сигналов процесса, блокирующую

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

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

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; /* <<< Добавлено */

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[] = "Entered childhandler\n";

50 static const char exited[] = "Exited childhandler\n";

51

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

53 for (i = 0; i < nkids; i++) {

54 if (kids[i] == NOT_USED)

55 continue;

56

57 retry:

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

59 strcpy(buf, "\treaped process ");

60 strcat(buf, format_num(ret));

61 strcat(buf, "\n");

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

63 kids[i] = NOT_USED;

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

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(&childset);

102 sigaddset(&childset, SIGCHLD);

103

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

105

106 for (nkids = 0; nkids < 5; nkids++) {

  • Читать дальше
  • 1
  • ...
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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