Linux программирование в примерах

На нашем литературном портале можно бесплатно читать книгу Linux программирование в примерах, Роббинс Арнольд-- . Жанр: Программирование / ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
Linux программирование в примерах
Название: Linux программирование в примерах
Дата добавления: 16 январь 2020
Количество просмотров: 975
Читать онлайн

Linux программирование в примерах читать книгу онлайн

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

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

 

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

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

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, restartingn", 27);

132   kill(si->si_pid, SIGCONT);

133   break;

134

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

136   write(1, "tchild continuedn", 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 dumpedn", 14);

149   break;

150

151  case CLD_KILLED:

152   write(1, " tchild killedn", 14);

153   break;

154

155  case CLD_TRAPPED:

156   write(1, "tchild trappedn", 15);

157   break;

158  }

159 }

Посредством функции

manage()
родитель обрабатывает изменение состояния в порожденном процессе,
manage()
вызывается, когда изменяется состояние и когда порожденный процесс завершился.

Строки 130–133 обрабатывают случай, когда потомок остановился; родитель возобновляет его, посылая

SIGCONT
.

Строки 135–137 выводят уведомление о возобновлении потомка. Это событие на системах GNU/Linux не происходит, и стандарт POSIX использует в этом случае невыразительный язык, просто говоря, что это событие может появиться, а не появится.

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

Другие случаи более специализированные. В случае события

CLD_KILLED
для получения дополнительных сведений было бы полезным значение
status
, заполненной функцией
waitpid()
.

Вот что происходит при запуске:

$ <b>ch10-status</b> /* Запуск программы */

waiting for signals

Entered childhandler /* Вход в обработчик сигнала */

  pid 24279 changed status

  child stopped, restarting /* Обработчик действует */

Exited childhandler

waiting for signals

  ---&gt; child restarted &lt;--- /* Из потомка */

Entered childhandler

  reaped process 24279 /* Обработчик родителя опрашивает потомка */

  child exited with status 42

К сожалению, поскольку нет способа гарантировать доставку по одному

SIGCHLD
на каждый процесс, ваша программа должна быть готова восстановить несколько потомков за один проход.

10.9. Сигналы, передающиеся через

fork()
и
exec()

Когда программа вызывает

fork()
, ситуация с сигналами в порожденном процессе почти идентична ситуации в родительском процессе. Установленные обработчики остаются на месте, заблокированные сигналы остаются заблокированными и т.д. Однако, любые ожидающие в родителе сигналы в потомке сбрасываются, включая установленный с помощью
alarm()
временной интервал. Это просто, и это имеет смысл.

Когда процесс вызывает одну из функций

exec()
, положение в новой программе следующее:

• Сигналы с установленным действием по умолчанию остаются с этим действием по умолчанию.

• Все перехваченные сигналы сбрасываются в состояние с действием по умолчанию.

• Сигналы, которые игнорируются, продолжают игнорироваться. Особым случаем является

SIGCHLD
. Если
SIGCHLD
до вызова
exec()
игнорировался, он может игнорироваться также и после вызова. В качестве альтернативы для него может быть восстановлено действие по умолчанию. То, что происходит на самом деле, стандартом POSIX намеренно не определяется. (Справочные страницы GNU/Linux не определяют, что делает Linux, и поскольку POSIX оставляет это не определенным, любой код, который вы пишете для использования
SIGCHLD
, должен быть подготовлен для обработки любого случая.)

• Сигналы, заблокированные до вызова

exec()
, остаются заблокированными и после вызова. Другими словами, новая программа наследует маску сигналов существующего процесса.

• Любые ожидающие сигналы (те, которые появились, но были заблокированы) сбрасываются. Новая программа не может их получить.

Перейти на страницу:
Комментариев (0)
название