Linux программирование в примерах
Шрифт:
Следующая программа,
ch10-reap1.с
, блокирует SIGCHLD
до тех пор, пока не будет готова восстановить потомков. 1 /* ch10-reap1.с --- демонстрирует управление SIGCHLD с использованием цикла */
2
3 #include <stdio.h>
4 #include <errno.h>
5 #include <signal.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9
10 #define MAX_KIDS 42
11 #define NOT_USED -1
12
13 pid_t kids[MAX_KIDS];
14 size_t nkids = 0;
Массив
NOT_USED
, он не представляет необработанного потомка. (Его инициализируют строки 89–90 внизу) nkids
указывает, сколько значений в kids
следует проверить. 16 /* format_num --- вспомогательная функция, поскольку нельзя использовать [sf]printf */
17
18 const char *format_num(int num)
19 {
20 #define NUMSIZ 30
21 static char buf[NUMSIZ];
22 int i;
23
24 if (num <= 0) {
25 strcpy(buf, "0");
26 return buf;
27 }
28
29 i = NUMSIZ - 1;
30 buf[i--] = '\0';
31
32 /* Преобразует цифры обратно в строку. */
33 do {
34 buf[i--] = (num % 10) + '0';
35 num /= 10;
36 } while (num > 0);
37
38 return &buf[i+1];
39 }
Поскольку обработчики сигналов не должны вызывать функции семейства
printf
, мы предусмотрели для преобразования десятичного сигнала или номера PID в строку простую «вспомогательную» функцию format_num
. Это примитивно, но работает. 41 /* childhandler --- перехват SIGCHLD, сбор сведений со всех доступных потомков */
42
43 void childhandler(int sig)
44 {
45 int status, ret;
46 int i;
47 char buf[100];
48 static const char entered[] = "Entered childhandler\n" ;
49 static const char exited[] = "Exited childhandler\n";
50
51 writed, entered, strlen(entered));
52 for (i =0; i < nkids; i++) {
53 if (kids[i] == NOT_USED)
54 continue;
55
56 retry:
57 if ((ret = waitpid(kids[i], &status, WNOHANG)) == kids[i]) {
58 strcpy(buf, "\treaped process ");
59 strcat(buf, format_num(ret));
60 strcat(buf, "\n");
61 write(1, buf, strlen(buf));
62 kids[i] = NOT_USED;
63 } else if (ret == 0) {
64 strcpy(buf, "\tpid ");
65 strcat(buf, format_num(kids[i]));
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
Главной частью обработчика сигнала является большой цикл, строки 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], это прерывание не должно случиться. Но этот пример показывает, как обработать все случаи.)
Поделиться:
Популярные книги
Старый, но крепкий 3
3. Культивация без насилия
Фантастика:
рпг
уся
фэнтези
5.00
рейтинг книги
Эмиссар
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Газлайтер. Том 28
28. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Сопротивление
11. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
7.33
рейтинг книги
Кодекс Охотника. Книга VII
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Чиновникъ Особых поручений
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сталин
3. Загадки жизни и смерти
Проза:
историческая проза
7.36
рейтинг книги
Ваше Сиятельство
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Идеальный мир для Лекаря 2
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
На границе империй. Том 7
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
Изменяющий-Механик. Компиляция. Книги 1-18
Собрание сочинений
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Я до сих пор князь. Книга XXII
22. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Чужое наследие
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Дважды одаренный. Том VIII
8. Дважды одаренный
Фантастика:
боевая фантастика
альтернативная история
аниме
попаданцы
5.00