Я понятия не имею, как это делает nginx, но, в принципе, он может просто exec
новый двоичный файл, содержащий слушающий сокет новый процесс (фактически, он остается тем же процессом, он просто заменяет программу, выполняющуюся в Это). Прослушивающий сокет имеет незавершенные входящие соединения, и, пока он достаточно быстр для загрузки, он должен иметь возможность начать их обработку до того, как он переполнится. Если нет, то он, вероятно, может сначала выполнить форк, выполнить exec и подождать, пока он загрузится до того момента, когда он будет готов обрабатывать входящие запросы, а затем передать команду прослушивающего сокета (дескрипторы файлов наследуются при разветвлении, оба имеют доступ это) через какой-то внутренний механизм, прежде чем выйти. Принимая во внимание ваши наблюдения, это похоже на то, что он делает (если ваш родительский процесс умирает, ваш ppid переназначается на init, т.е. pid 1)
Если у него есть несколько процессов, конкурирующих за прием в одном и том же сокете прослушивания (опять же, я понятия не имею, как это делает nginx, возможно, у него есть процесс диспетчеризации?), То вы можете заменить их один за другим, заказав их выполнить новую программу, как указано выше, но по одному, чтобы никогда не уронить мяч. Обратите внимание, что во время такого процесса никогда не будет никаких новых pids или изменений отношения родитель / потомок.
По крайней мере, я думаю, что, вероятно, я бы это сделал, с макушки головы.