Solaris 10: быстрое обнаружение выхода SIGCHLD / процесса - PullRequest
1 голос
/ 23 февраля 2010

В Solaris 10 у меня есть родительский и дочерний процессы. Я убиваю дочерний процесс с помощью kill -KILL. Я хочу, чтобы это было возможно как можно быстрее в родительском процессе (это главная / подчиненная система, и цель заключается в том, чтобы родитель запросил резервное копирование как можно быстрее). Родительский процесс должен знать, что у ребенка запущен для выхода (ему не нужно ждать, пока у ребенка выйдет ).

В системе, с которой я работаю, я вижу задержку около 200 мс между отправкой SIGKILL и родительским процессом, получающим SIGCHLD. Я не думаю, что смогу сократить это время просто из-за размера дочернего процесса и времени, необходимого для его выхода - исправьте меня, если я ошибаюсь.

Я думаю, что мои варианты: - Не посылай SIGKILL ребенку. Вместо этого отправьте сигнал родителю, чтобы он мог убить дочернего элемента (и, следовательно, мгновенно узнает, что дочерний процесс завершается). Это не идеально, потому что некоторые из команд kill -KILL находятся вне моего контроля, поэтому я не могу заменить их другим сигналом для родителя. - Примите участие в обработке завершения для ребенка (я не думаю, что это возможно, потому что SIGKILL не может быть пойман). - Есть еще идеи?

Спасибо за любой совет. NickB

Ответы [ 4 ]

0 голосов
/ 26 июня 2010

Вы можете использовать не так широко известную особенность дверей Solaris . В родительском процессе создайте дверь с помощью door_create с атрибутом DOOR_UNREF, что означает:

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

Затем форк, так что у вас есть две ссылки на дескриптор двери. Когда ваш дочерний процесс умирает, функция двери вызывается в родительском процессе, потому что ссылки дескриптора двери уменьшаются до единицы.

Двери Solaris должны быть очень быстрыми, но, честно говоря, я никогда не измерял время доставки в данном конкретном случае. Дайте мне знать, если это работает для вас.

0 голосов
/ 23 февраля 2010

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

После этого вы можете игнорировать SIGCHLD и получить дополнительный бонус от избежания асинхронного кодирования.

Предложение paxdiablo об использовании семафоров также может быть тем, что вы хотите: при запуске дочерний элемент блокирует семафор. Если вы запустите два дочерних процесса, один из них будет запущен, а другой будет ожидать семафор. Как только первый убит, второй начинает работать.

0 голосов
/ 25 февраля 2010

Это предположение, но как родительский процесс обнаруживает SIGCHLD? Если вы используете обработчик сигнала, вы можете получить некоторую скорость, используя выделенный поток сигнала.

По сути, вы запускаете отдельный поток для обработки сигнала. Все потоки (включая сигнальный поток) должны вызвать pthread_sigmask(), чтобы заблокировать получение SIGCHLD. Затем поток сигналов вызывает sigwait() с маской, включающей SIGCHLD. sigwait () будет блокироваться до получения SIGCHLD, а затем возвращаться при получении сигнала.

Основным преимуществом использования сигнального потока является то, что вы можете обрабатывать сигналы в каком-либо основном цикле без ограничений обработчика сигнала или прерывания сигнала чем-то еще, что может делать процесс. Я предпочитаю предположить, что ядро ​​может быть дешевле доставлять сигнал потоку, используя этот метод.

0 голосов
/ 23 февраля 2010

Я не уверен, что вы получите намного быстрее, чем доставка SIGCHLD. Возможно, вы захотите подумать о том, чтобы, если возможно, изменить архитектуру приложения, чтобы оно было ведущим / несколькими ведомыми.

Если вы работаете с одним ведущим и пятью ведомыми, то потеря одного подчиненного приведет к снижению емкости на 20%, а не к полной потере. И, надеюсь, мастер сможет достаточно быстро достать другого раба, прежде чем его заметят.

Другим возможным преимуществом этого является наличие запасных рабов, ожидающих своего часа, уже запущенных, но ожидающих семафора или другого сигнала, чтобы начать выполнять реальную работу. Вполне возможно, что это может помочь, даже если вы не можете запускать несколько подчиненных устройств одновременно, поскольку это устранит хотя бы часть задержки (ожидание загрузки процесса). Просто подайте сигнал запасному ребенку, чтобы начать, как только появится SIGCHLD.

...