двойная вилка с использованием vfork - PullRequest
3 голосов
/ 11 апреля 2010

HI
Я пишу часть сервера, которая должна отправлять некоторые другие дочерние процессы.
Поскольку я хочу ждать некоторых процессов и отправлять другие, не дожидаясь завершения, я использую двойную вилку для второго типа процессов (таким образом, избегая процессов зомби).
Проблема в том, что у моего сервера много памяти, поэтому разветвление занимает много времени (даже в Linux используется вилка копирования при записи, которая копирует только таблицы подкачки)
Я хочу заменить fork () на vfork (), и это легко для второго форка (так как он вызывает только execve () в дочернем элементе), но я не смог найти способ заменить первый. * Кто-нибудь знает, как я могу это сделать?
Спасибо!

Сервер представляет собой Linux (RH5U4), написанный на C ++.

Ответы [ 5 ]

2 голосов
/ 12 апреля 2010

Почему бы не сделать так, чтобы новый exec'd сам делал другой форк?Таким образом, копировать таблицы страниц будут только небольшой простой процесс?

РЕДАКТИРОВАТЬ:

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

1 голос
/ 06 июля 2017

Полагаю, вы можете использовать ответ на другой вопрос, который я задавал, по той же причине. Вы можете vfork() + exec() в исполняемый файл, который снова разветвляется. Смотрите setuid () перед вызовом execv () в vfork () / clone ()

1 голос
/ 21 февраля 2012

Не делайте двойную вилку. Обработка SIGCHLD для сохранения ошибки, ожидания вызова, восстановления ошибки.

1 голос
/ 12 апреля 2010

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

1 голос
/ 11 апреля 2010

vfork() можно использовать только для разветвления, а затем вызвать exec или exit. Кроме того, vfork() будет блокировать родительский процесс, пока дочерний процесс не вызовет _exit или exec, что почти наверняка не соответствует желаемому поведению.

Причина этого в том, что vfork() не делает никаких копий каких-либо данных, включая стек, для нового процесса. Таким образом, все совместно используются, и очень легко случайно изменить то, что родительский процесс не может обработать. Поскольку данные совместно используются без копий, родительский процесс не может продолжить работу одновременно с дочерним процессом, поэтому он должен дождаться, пока дочерний процесс _exit или вызовет exec, чтобы он больше не использовал данные при запуске родительского процесса изменить его.

...