» » » Арнольд Роббинс - Linux программирование в примерах


Авторские права

Арнольд Роббинс - Linux программирование в примерах

Здесь можно скачать бесплатно "Арнольд Роббинс - Linux программирование в примерах" в формате fb2, epub, txt, doc, pdf. Жанр: Программное обеспечение, издательство Кудиц-Образ, год 2005. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Арнольд Роббинс - Linux программирование в примерах
Рейтинг:
Название:
Linux программирование в примерах
Издательство:
Кудиц-Образ
Год:
2005
ISBN:
5-9579-0059-1
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

Описание книги "Linux программирование в примерах"

Описание и краткое содержание "Linux программирование в примерах" читать бесплатно онлайн.



В книге рассмотрены вопросы, связанные с программированием под Linux: файловый ввод/вывод, метаданные файлов, основы управления памятью, процессы и сигналы, пользователи и группы, вопросы интернационализации и локализации, сортировка, поиск и многие другие. Много внимания уделено средствам отладки, доступным под GNU Linux. Все темы иллюстрируются примерами кода, взятого из V7 UNIX и GNU. Эта книга может быть полезна любому, кто интересуется программированием под Linux.






  pid 2706 not available yet

Exited childhandler

waiting for signals

Entered childhandler /* И так далее */

  reaped process 2704

  pid 2705 not available yet

  pid 2706 not available yet

Exited childhandler

waiting for signals

Entered childhandler

  reaped process 2705

  pid 2706 not available yet

Exited childhandler

waiting for signals

Entered childhandler

  reaped process 2706

Exited childhandler

В данном примере на каждый процесс поступает ровно один SIGCHLD! Хотя это прекрасно и полностью воспроизводимо на этой системе, это также необычно. Как на более раннем, так и на более позднем ядре и на Solaris программа получает один сигнал для более чем одного потомка:

$ uname -a /* Отобразить версию системы */

Linux example2 2.4.22-1.2115.npt1 #1 Wed Oct 29 15:42:51 EST 2003 i686 i686 i386 GNU/Linux

$ ch10-reap2 /* Запуск программы */

waiting for signals

Entered childhandler /* Обработчик сигнала вызван лишь однажды */

  reaped process 9564

  reaped process 9565

  reaped process 9566

  reaped process 9567

  reaped process 9568

Exited childhandler

ЗАМЕЧАНИЕ. В коде для ch10-reap2.c есть один важный дефект — состояние гонки. Взгляните еще раз на строки 106–112 в ch10-reap2.c. Что случится, если SIGCHLD появится при исполнении этого кода? Массив kids и переменные nkids и kidsleft могут оказаться разрушенными: код в main добавляет новый процесс, но обработчик сигнала вычитает один.

Этот пример кода является отличным примером критического раздела; он не должен прерываться при исполнении. Правильным способом работы с этим кодом является заключение его между вызовами, которые сначала блокируют, а затем разблокируют SIGCHLD.

10.8.3.3. Строгий родительский контроль

Структура siginfo_t и перехватчик сигнала с тремя аргументами дают возможность узнать, что случилось с потомком. Для SIGCHLD поле si_code структуры siginfo_t указывает причину посылки сигнала (остановка, возобновление, завершение порожденного процесса и т.д.). В табл. 10.5 представлен полный список значений. Все они определены в качестве расширения XSI стандарта POSIX.

Следующая программа, ch10-status.c, демонстрирует использование структуры siginfo_t.

1  /* ch10-status.c --- демонстрирует управление SIGCHLD, используя обработчик с 3 аргументами */

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 void manage(siginfo_t *si);

11

/* ...не изменившийся для format_num() код опущен... */


Таблица 10.5. Значения si_code XSI для SIGCHLD

Значение Смысл CLD_CONTINUED Остановленный потомок был возобновлен. CLD_DUMPED Потомок завершился с ошибкой, создан образ процесса CLD_EXITED Потомок завершился нормально. CLD_KILLED Потомок был завершен сигналом CLD_STOPPED Порожденный процесс был остановлен. CLD_TRAPPED Трассируемый потомок остановлен (Это условие возникает, когда программа трассируется — либо из отладчика, либо для мониторинга реального времени В любом случае, вы вряд ли увидите его в обычных ситуациях.)

Строки 3–8 включают стандартные заголовочные файлы, строка 10 объявляет manage(), которая имеет дело с изменениями состояния потомка, а функция format_num() не изменилась по сравнению с предыдущим.

37 /* childhandler --- перехват SIGCHLD, сбор данных лишь об одном потомке */

38

39 void childhandler(int sig, siginfo_t *si, void *context)

40 {

41  int status, ret;

42  int i;

43  char buf[100];

44  static const char entered[] = "Entered childhandler\n";

45  static const char exited[] = "Exited childhandler\n";

46

47  write(1, entered, strlen(entered));

48 retry:

49  if ((ret = waitpid(si->si_pid, &status, WNOHANG)) == si->si_pid) {

50   strcpy(buf, "\treaped process ");

51   strcat(buf, format_num(si->si_pid));

52   strcat(buf, "\n");

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

54   manage(si); /* обработать то, что произошло */

55  } else if (ret > 0) {

56   strcpy(buf, "\treaped unexpected pid ");

57   strcat(buf, format_num(ret));

58   strcat(buf, "\n");

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

60   goto retry; /* почему бы нет? */

61  } else if (ret == 0) {

62   strcpy(buf, "\tpid ");

63   strcat(buf, format_num(si->si_pid));

64   strcat(buf, " changed status\n");

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

66   manage(si); /* обработать то, что произошло */

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

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

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

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


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

Похожие книги на "Linux программирование в примерах"

Книги похожие на "Linux программирование в примерах" читать онлайн или скачать бесплатно полные версии.


Понравилась книга? Оставьте Ваш комментарий, поделитесь впечатлениями или расскажите друзьям

Все книги автора Арнольд Роббинс

Арнольд Роббинс - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Отзывы о "Арнольд Роббинс - Linux программирование в примерах"

Отзывы читателей о книге "Linux программирование в примерах", комментарии и мнения людей о произведении.

А что Вы думаете о книге? Оставьте Ваш отзыв.