Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
117 }118119 return 0;120 }Программа
main()SA_SIGINFOSIGCHLDСтрока 110 создает порожденный процесс. Строки 113–117 продолжаются в родителе, используя для ожидания входящих сигналов
sigsuspend()123 /* manage --- разрешение различных событий, которые могут случиться с потомком */124125 void manage(siginfo_t *si)126 {127 char buf[100];128129 switch (si->si_code) {130 case CLD_STOPPED:131 write(1, "tchild stopped, restartingn", 27);132 kill(si->si_pid, SIGCONT);133 break;134135 case CLD_CONTINUED: /* not sent on Linux */136 write(1, "tchild continuedn", 17);137 break;138139 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;146147 case CLD_DUMPED:148 write(1, "tchild dumpedn", 14);149 break;150151 case CLD_KILLED:152 write(1, " tchild killedn", 14);153 break;154155 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_KILLEDstatuswaitpid()Вот что происходит при запуске:
$ <b>ch10-status</b> /* Запуск программы */waiting for signalsEntered childhandler /* Вход в обработчик сигнала */ pid 24279 changed status child stopped, restarting /* Обработчик действует */Exited childhandlerwaiting for signals ---> child restarted <--- /* Из потомка */Entered childhandler reaped process 24279 /* Обработчик родителя опрашивает потомка */ child exited with status 42К сожалению, поскольку нет способа гарантировать доставку по одному
SIGCHLD10.9. Сигналы, передающиеся через
fork()exec()Когда программа вызывает
fork()alarm()Когда процесс вызывает одну из функций
exec()• Сигналы с установленным действием по умолчанию остаются с этим действием по умолчанию.
• Все перехваченные сигналы сбрасываются в состояние с действием по умолчанию.
• Сигналы, которые игнорируются, продолжают игнорироваться. Особым случаем является
SIGCHLDSIGCHLDexec()SIGCHLD• Сигналы, заблокированные до вызова
exec()• Любые ожидающие сигналы (те, которые появились, но были заблокированы) сбрасываются. Новая программа не может их получить.