$ sed -e '
/^#[[:blank:]]*second-option[)]$/!b
:a;$!N;s/\\$/&/;ta
s/\(\n\)#/\1/g;s/^#//
' file
В командной строке bash
вPosix sed
Или следующее с Gnu sed:
$ sed -e '/^#\s*second-option[)]$/,/[^\]$/s/^#//' file
Если установлен, обработчик сигнала вызывается ядром в процессе, когда дочерний элемент изменяет состояние (, как правило, при выходе. )но по умолчанию он не пожинает потомок. Вызов wait (2 )или waitpid (2 )внутри или снаружи обработчика по-прежнему необходим, чтобы потомок был собран. Если SA _NOCLDWAIT указан как опция для sigaction (2 )при установке обработчика SIGCHLD,тогда ядро автоматически пожинает потомок после того, как обработчик сигнала будет доставлен, и для пожинания не требуется вызов ожидания (2 ).
См. обсуждение параметров SA _NOCLDSTOP и SA _NOCLDWAIT на справочной странице sigaction (2 ), поскольку они относятся к SIGCHLD.
Кроме того, рассмотрите возможность использования sigaction (2 )вместо сигнала (2 )и позволяет использовать обработчик сигнала с тремя аргументами, указав SA _SIGINFO. Ссылка на структуру siginfo _t будет содержать дополнительную полезную информацию о том, почему доставляется SIGCHLD.
У меня недостаточно баллов для комментариев, но это ответ на ваш вопрос.
Поднятый сигнал активирует функцию обработчика, которую вы установили для этого конкретного типа сигнала, которым в вашем примере является SIGCHLD.
Пример здесь.https://stackoverflow.com/questions/13792900/signal-and-sigchld-what-does-it-do
Как видно из приведенной выше ссылки, ожидание ()не обязательно должно находиться внутри обработчика.
Это просто ждет завершения дочернего процесса.
Таким образом, прямой связи как таковой нет, просто сигнал SIGCHLD будет генерируется, когда разветвленный дочерний процесс умирает, и что ожидание ()будет ждать, пока дочерний процесс не завершится должным образом.
wait()
— устаревший системный вызов UNIX 1970-х годов, а waitpid()
— устаревший системный вызов UNIX 1980-х годов.
В 1988 году был представлен улучшенный интерфейс waitid()
.
signal()
также является устаревшим интерфейсом 1970-х годов. Последний интерфейс называется sigaction()
и позволяет управлять поведением сигналов. Типичным вызовом в вашем случае будет:
struct sigaction sa;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART|SA_SIGINFO;
sigaction(SIGCHLD, &sa, NULL);
Если вы добавите SA_NOCLDWAIT
к sa.sa_flags
, вам вообще не нужно вызывать wait*()
, и система не будет поддерживать зомби-процессы, пока не будет сделан вызов wait*()
.
Если вы добавите SA_NOCLDSTOP
, обработчик SIGCHLD не будет вызываться, если завершается процесс cild.
Если генерируется SIGCHLD
, это вызовет функцию:
void handler(int sig, siginfo_t *sip, void *context)
когда дочерний процесс умер. Параметр sig
заполняется номером сигнала SIGCHLD
, а второй параметр заполняется той же информацией, что и при вызове waitid()
, как и в:
struct siginfo si;
ret = waitid(P_PID, pid, &si, WEXITED|WSTOPPED|WTRAPPED);
Таким образом, если вас не интересует статус дочерних элементов, можно сообщить об этом системе, а если вы не заинтересованы в вызове wait*()
, но все же хотите получить статус процесса, вы можете сообщить об этом системе и использовать информацию из второго параметра функции обработчика сигнала.
Когда дочерний процесс умирает и struct siginfo
проверяется, заполняются следующие поля:
si.si_signo /* The signal number SIGCHLD */
si.si_code /* The reason for the child to exit */
si.si_status /* Either the parameter to exit(r) or signal number */
si.si_pid /* The process is of the child that died */
Если si.si_code
содержит значение CLD_EXITED
, тоsi.si_status
(в системе POSIX )содержит полные 32 бита кода exit()
.
Если si.si_code
содержит CLD_KILLED
, CLD_DUMPED
, CLD_TRAPPED
, CLD_STOPPED
или CLD_CONTINUED
, то si.si_code
содержит номер сигнала, вызвавшего изменение состояния.