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

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

Шрифт:

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;

Массив потомков отслеживает ID порожденных процессов. Если элемент содержит

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

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

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

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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