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

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

Жанры

Linux программирование в примерах
Шрифт:

66 strcat(buf, " not available yet\n");

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

68 } else if (ret == -1 && errno == EINTR) {

69 write(1, "\tretrying\n", 10);

70 goto retry;

71 } else {

72 strcpy(buf, "\twaitpid failed: ");

73 strcat(buf, strerror(errno));

74 strcat(buf, "\n");

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

76 }

77 }

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

79 }

Строки 51

и 58 выводят «входное» и «завершающее» сообщения, так что мы можем ясно видеть, когда вызывается обработчик сигнала. Другие сообщения начинаются с ведущего символа TAB.

Главной частью обработчика сигнала является большой цикл, строки 52–77. Строки 53–54 проверяют на

NOT_USED
и продолжают цикл, если текущий слот не используется.

Строка 57 вызывает

waitpid
с PID текущего элемента
kids
. Мы предусмотрели опцию
WNOHANG
, которая заставляет
waitpid
возвращаться немедленно, если затребованный потомок недоступен. Этот вызов необходим, так как возможно, что не все потомки завершились.

Основываясь на возвращенном значении, код предпринимает соответствующее действие. Строки 57–62 обрабатывают случай обнаружения потомка, выводя сообщение и помещая в соответствующий слот в

kids
значение
NOT_USED
.

Строки 63–67 обрабатывают случай, когда затребованный потомок недоступен. В этом случае возвращается значение 0, поэтому выводится сообщение, и выполнение продолжается.

Строки 68–70 обрабатывают случай, при котором был прерван системный вызов. В этом случае самым подходящим способом обработки является

goto
обратно на вызов
waitpid
. (Поскольку
main
блокирует все сигналы при вызове обработчика сигнала [строка 96], это прерывание не должно случиться. Но этот пример показывает, как обработать все случаи.)

Строки 71–76 обрабатывают любую другую ошибку, выводя соответствующее сообщение об ошибке.

81 /* main --- установка связанных с порожденными процессами сведений и сигналов, создание порожденных процессов */

82

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

84 {

85 struct sigaction sa;

86 sigset_t childset, emptyset;

87 int i;

88

89 for (i = 0; i < nkids; i++)

90 kids[i] = NOT_USED;

91

92 sigemptyset(&emptyset);

93

94 sa.sa_flags =
SA_NOCLDSTOP;

95 sa.sa_handler = childhandler;

96 sigfillset(&sa.sa_mask); /*
блокировать все при вызове обработчика */

97 sigaction(SIGCHLD, &sa, NULL);

98

99 sigemptyset(&childset);

100 sigaddset(&childset, SIGCHLD);

101

102 sigprocmask(SIG_SETMASK, &childset, NULL); /* блокировать его в коде main */

103

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

105 if ((kids[nkids] = fdrk) == 0) {

106 sleep(3);

107 _exit(0);

108 }

109 }

110

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

112

113 printf("waiting for signal\n");

114 sigsuspend(&emptyset);

115

116 return 0;

117 }

Строки 89–90 инициализируют

kids
. Строка 92 инициализирует
emptyset
. Строки 94–97 настраивают и устанавливают обработчик сигнала для
SIGCHLD
. Обратите внимание на использование в строке 94
SA_NOCLDSTOP
, тогда как строка 96 блокирует все сигналы при вызове обработчика.

Строки 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

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

Часовое имя

Щерба Наталья Васильевна
4. Часодеи
Детские:
детская фантастика
9.56
рейтинг книги
Часовое имя

Ох уж этот Мин Джин Хо 4

Кронос Александр
4. Мин Джин Хо
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 4

Аутсайдер

Астахов Евгений Евгеньевич
11. Сопряжение
Фантастика:
боевая фантастика
космическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Аутсайдер

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

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

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Волк: лихие 90-е

Киров Никита
1. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк: лихие 90-е

Магия чистых душ

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.40
рейтинг книги
Магия чистых душ

Релокант. По следам Ушедшего

Ascold Flow
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. По следам Ушедшего

(Не) Все могут короли

Распопов Дмитрий Викторович
3. Венецианский купец
Фантастика:
попаданцы
альтернативная история
6.79
рейтинг книги
(Не) Все могут короли

Изгой Проклятого Клана. Том 2

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

(Бес) Предел

Юнина Наталья
Любовные романы:
современные любовные романы
6.75
рейтинг книги
(Бес) Предел

Отверженный VIII: Шапка Мономаха

Опсокополос Алексис
8. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Отверженный VIII: Шапка Мономаха

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок