Недавно мы опубликовали перевод статьи о конвейерах в Unix, у автора которой есть ещё немало подобных материалов. В той публикации мы устроили опрос о целесообразности перевода других статей того же автора. Большинство принявших участие в опросе эту идею поддержало. Поэтому сегодня мы предлагаем вашему вниманию перевод ещё одного материала о Unix, который посвящён
В современных версиях Unix сигнал
В V7 программы, вроде командной оболочки, обладали достаточно простой системой обработки завершения работы дочерних процессов. Всё это обычно работало в синхронном режиме. Когда эти программы что-то запускали (или когда запускался встроенный механизм оболочки
Когда в BSD появилась система управления заданиями (job control), там это тоже было реализовано, в результате фоновые задания, которые пытались писать в терминал или читать из него, могли быть автоматически приостановлены. Это нужно в том случае, когда задания могут менять состояние, становясь то фоновыми задачами, то задачами переднего плана. Программу можно запустить в виде задачи переднего плана, а потом, если на её работу нужно слишком много времени, перевести её в фоновый режим. Когда же она готова будет вывести результаты своей деятельности, её снова можно сделать задачей переднего плана. Но реализация подобных возможностей означает, что оболочка, поддерживающая систему управления заданиями, теперь нуждается в сведениях об изменениях состояния процессов, поступающих к ней в асинхронном режиме. Если оболочка ожидает от вас ввода очередной команды (то есть — читает данные из самого терминала и заблокирована в
Если в общих чертах описать
(Командные оболочки, использующие системы управления заданиями, не обязаны немедленно реагировать на изменение состояния дочерних процессов. И некоторые из них работают именно так. Поведение оболочки может даже зависеть от её настроек, что вполне разумно, так как некоторым пользователям не понравилось бы, если бы их отвлекали бы сообщения оболочки в те моменты, когда они вводят команды или размышляют. Такие пользователи предпочли бы просто нажать на клавишу
P.S. В 4.2 BSD, кроме того, появился вызов wait3(). Он, что произошло впервые, позволил процессам проверять состояние дочерних процессов без блокировки. Это — механизм, который можно использовать в командной оболочке в том случае, если нужно лишь проверить состояние завершённых и приостановленных процессов непосредственно перед продолжением работы.
Пользуетесь ли вы сигналом SIGCHLD?
SIGCHLD
.В современных версиях Unix сигнал
SIGCHLD
отправляется процессу в том случае, если один из его дочерних процессов завершается, а так же — при других изменениях состояния дочернего процесса. Перехват SIGCHLD
позволяет реализовать удобный способ выяснения момента завершения работы дочерних процессов в то время когда программа занимается другими делами, а его игнорирование приводит к исчезновению этих процессов, а не к превращению их в процессы-зомби. Несмотря на все эти полезности SIGCHLD
отсутствовал в V7 Unix. Он был добавлен в 4.2 BSD, и, независимо, в System III (как SIGCLD
).В V7 программы, вроде командной оболочки, обладали достаточно простой системой обработки завершения работы дочерних процессов. Всё это обычно работало в синхронном режиме. Когда эти программы что-то запускали (или когда запускался встроенный механизм оболочки
wait
), они вызывали wait() до тех пор, пока либо не возвращался код ошибки, либо не возвращался ID процесса, появления которого они ожидали. Если нужно было это прервать, использовалось сочетание клавиш ^C
, а обработчик сигнала SIGINT
оболочки делал всё что нужно. В V7 этого было достаточно, так как оболочке V7, на самом деле, не нужно было знать об изменениях состояния дочерних процессов, за исключением тех случаев, когда эти сведения запрашивал у неё программист.Когда в BSD появилась система управления заданиями (job control), там это тоже было реализовано, в результате фоновые задания, которые пытались писать в терминал или читать из него, могли быть автоматически приостановлены. Это нужно в том случае, когда задания могут менять состояние, становясь то фоновыми задачами, то задачами переднего плана. Программу можно запустить в виде задачи переднего плана, а потом, если на её работу нужно слишком много времени, перевести её в фоновый режим. Когда же она готова будет вывести результаты своей деятельности, её снова можно сделать задачей переднего плана. Но реализация подобных возможностей означает, что оболочка, поддерживающая систему управления заданиями, теперь нуждается в сведениях об изменениях состояния процессов, поступающих к ней в асинхронном режиме. Если оболочка ожидает от вас ввода очередной команды (то есть — читает данные из самого терминала и заблокирована в
read()
), а фоновая программа приостановлена после попытки доступа к терминалу, то вам, вероятно, хотелось бы, чтобы оболочка тут же вам об этом сообщила, не дожидаясь того момента, пока вы что-то введёте в терминал. Для того чтобы получать немедленные уведомления о событиях такого рода, нужен сигнал, который отправляется родительскому процессу тогда, когда меняется состояние дочернего процесса, в том числе — тогда, когда он приостанавливается вышеописанным образом. Это — сигнал SIGCHLD
.Если в общих чертах описать
SIGCHLD
, то можно сказать, что этот сигнал позволяет программам реагировать на завершение работы дочерних процессов даже в ситуациях, когда эти программы заняты другими делами. Это, в целом, полезная возможность. Видимо, именно поэтому в System III добавили собственную версию этого сигнала, несмотря даже на отсутствие там системы управления заданиями.(Командные оболочки, использующие системы управления заданиями, не обязаны немедленно реагировать на изменение состояния дочерних процессов. И некоторые из них работают именно так. Поведение оболочки может даже зависеть от её настроек, что вполне разумно, так как некоторым пользователям не понравилось бы, если бы их отвлекали бы сообщения оболочки в те моменты, когда они вводят команды или размышляют. Такие пользователи предпочли бы просто нажать на клавишу
Return
в тот момент, когда им нужно взглянуть на подобные сообщения.)P.S. В 4.2 BSD, кроме того, появился вызов wait3(). Он, что произошло впервые, позволил процессам проверять состояние дочерних процессов без блокировки. Это — механизм, который можно использовать в командной оболочке в том случае, если нужно лишь проверить состояние завершённых и приостановленных процессов непосредственно перед продолжением работы.
Пользуетесь ли вы сигналом SIGCHLD?