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

Программа 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, restarting\n", 27);

132   kill(si->si_pid, SIGCONT);

133   break;

134

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

136   write(1, "\tchild continued\n", 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 dumped\n", 14);

149   break;

150

151  case CLD_KILLED:

152   write(1, " \tchild killed\n", 14);

153   break;

154

155  case CLD_TRAPPED:

156   write(1, "\tchild trapped\n", 15);

157   break;

158  }

159 }

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

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

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

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

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

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

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

waiting for signals

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

  pid 24279 changed status

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

Exited childhandler

waiting for signals

  ---> child restarted <--- /* Из потомка */

Entered childhandler

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

  child exited with status 42

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

<p>10.9. Сигналы, передающиеся через <code>fork()</code></span><span> и </span><span><code>exec()</code></span><span></p>

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

Когда процесс вызывает одну из функций exec(), положение в новой программе следующее:

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

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

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

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

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

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