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

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

Жанры

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

69 goto retry;

70 } else {

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

72 strcat(buf, strerror(errno));

73 strcat(buf, "\n");

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

75 }

76

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

78 }

Обработчик сигнала похож на показанные ранее. Обратите внимание на список аргументов (строка 39) и на то, что нет цикла.

Строки 49–54 обрабатывают завершение процесса, включая вызов

manage
для вывода состояния.

Строки 55–60 обрабатывают случай неожиданного завершения потомка. Этого не должно происходить, поскольку обработчику сигнала передается специфическая для определенного порожденного процесса информация.

Строки 61–66 представляют для нас интерес: возвращаемое значение для изменений состояния равно 0.

manage
имеет дело с деталями (строка 66).

Строки 67–69 обрабатывают прерывания, а строки 70–75 распоряжаются ошибками

80 /* child --- что сделать в порожденном процессе */

81

82 void child(void)

83 {

84 raise(SIGCONT); /* должен быть проигнорирован */

85 raise(SIGSTOP); /* заснуть, родитель снова разбудит */

86 printf("\t---> child restarted <---\n");

87 exit(42); /* нормальное завершение, дать возможность родителю получить значение */

88 }

Функция

child
обрабатывает поведение порожденного процесса, предпринимая действия для уведомления родителя [113] . Строка 84 посылает
SIGCONT
, что может вызвать получение родителем события
CLD_CONTINUED
. Строка 85 посылает
SIGSTOP
, который останавливает процесс (сигнал не может быть перехвачен) и вызывает для родителя событие
CLD_STOPPED
. Когда родитель возобновляет порожденный процесс, последний выводит сообщение, что он снова активен, а затем завершается с известным статусом завершения.

113

Возможно, лучшим именем для функции было бы

child_at_school
[ребенок_в_школе] — Примеч. автора.

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

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

91

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

93 {

94 pid_t kid;

95 struct sigaction sa;

96 sigset_t childset, emptyset;

97

98 sigemptyset(&emptyset);

99

100 sa.sa_flags = SA_SIGINFO;

101 sa.sa_sigaction = childhandler;

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

103 sigaction(SIGCHLD, &sa, NULL);

104

105 sigemptyset(&childset);

106 sigaddset(&childset, SIGCHLD);

107

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

109

110 if ((kid = fork) == 0)

111 child;

112

113 /* здесь выполняется родитель */

114 for (;;) {

115 printf("waiting for signals\n");

116 sigsuspend(&emptyset);

117 }

118

119 return 0;

120 }

Программа

main
все устанавливает. Строки 100–103 помещают на место обработчик. Строка 100 устанавливает флаг
SA_SIGINFO
таким образом, что используется обработчик с тремя аргументами. Строки 105–108 блокируют
SIGCHLD
.

Строка 110 создает порожденный процесс. Строки 113–117 продолжаются в родителе, используя для ожидания входящих сигналов

sigsuspend
.

123 /* manage --- разрешение различных событий, которые могут случиться с потомком */

124

125 void manage(siginfo_t *si)

126 {

127 char buf[100];

128

129 switch (si->si_code) {

130 case CLD_STOPPED:

131 write(1, "\tchild stopped, restarting\n", 27);

132 kill(si->si_pid, SIGCONT);

133 break;

134

135 case CLD_CONTINUED: /* not sent on Linux */

136 write(1, "\tchild continued\n", 17);

137 break;

138

139 case CLD_EXITED:

140 strcpy(buf, "\tchild exited with status ");

141 strcat(buf, format_num(si->si_status));

142 strcat(buf, "\n");

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

144 exit(0); /* we're done */

145 break;

146

147 case CLD_DUMPED:

148 write(1, "\tchild dumped\n", 14);

149 break;

150

151 case CLD_KILLED:

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

Наследие Маозари 3

Панежин Евгений
3. Наследие Маозари
Фантастика:
рпг
аниме
5.00
рейтинг книги
Наследие Маозари 3

На границе империй. Том 10. Часть 9

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 9

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

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

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Гнездо Седого Ворона

Свержин Владимир Игоревич
2. Трактир "Разбитые надежды"
Фантастика:
боевая фантастика
7.50
рейтинг книги
Гнездо Седого Ворона

Леди Малиновой пустоши

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

Я царь. Книга XXVIII

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

Ренегат космического флота

Борчанинов Геннадий
4. Звезды на погонах
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Ренегат космического флота

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Кай из рода красных драконов 2

Бэд Кристиан
2. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов 2

Назад в СССР 5

Дамиров Рафаэль
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Назад в СССР 5

Звездная Кровь. Изгой V

Елисеев Алексей Станиславович
5. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
технофэнтези
рпг
фантастика: прочее
5.00
рейтинг книги
Звездная Кровь. Изгой V

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Отмороженный 5.0

Гарцевич Евгений Александрович
5. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 5.0