Linux: разница между разветвлением дважды и демоном (ise)

Я пытался написать базовый многопроцессорный tcp-сервер, который разветвляет процесс для каждого нового accept().

Мне не нужен родительский процесс для ожидания дочерних процессов. Я сталкивался с двумя решениями - дважды раздваивать и демонизировать.

  1. Какая разница между этими двумя?
  2. Что больше подходит в этом сценарии?
  3. Какие факторы следует учитывать при выборе одного из них?

2 ответа

Есть небольшая разница.

Форкинг дважды: промежуточный дочерний процесс не может стать зомби при условии, что он завершился и его ожидал родительский процесс. Внук не может стать зомби, так как его родитель (промежуточный дочерний процесс) вышел, поэтому внук - сирота. Сирота (внука) наследуется init, и если она выходит сейчас, ответственность за ее очистку лежит на системе. Таким образом, родительский процесс освобождается от обязанности ожидания получения сигнала состояния выхода от дочернего процесса, а также родитель может быть занят выполнением какой-либо другой работы. Это также позволяет ребенку бегать в течение длительного времени, так что краткосрочному родителю не нужно ждать этого времени.

Демон: предназначен для программ, желающих отсоединиться от управляющего терминала и работать в фоновом режиме в качестве системных демонов. Не имеет управляющего терминала.

Решение подхода зависит от требования / сценария в руке.

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

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

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

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

Также обратите внимание, что двойное разветвление не только выдает ответственность за управление процессами, но также лишает возможности управления процессами. Является ли это хорошим компромиссом, зависит от ситуации.

Другие вопросы по тегам