Читаем Linux программирование в примерах полностью

Массив потомков отслеживает 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 и продолжают цикл, если текущий слот не используется.

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

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

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

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

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных