Как уже говорилось, на справочной странице vfork
все ясно.
Эта тема дает хорошее описание fork
, vfork
, clone
и exec
.
Ниже приведены некоторые часто пропускаемые различия между fork
и vfork
, с которыми я столкнулся в некоторых встроенных системах Linux 2.6.3x, с которыми работал.
Даже при использовании методов копирования при записи fork
завершается ошибкой, если у вас недостаточно памяти для дублирования памяти, используемой родительским процессом. Например, если родительский процесс использует 2 ГБ резидентной памяти (т. Е. Память, которая используется, а не только выделена), fork
завершится неудачно, если у вас осталось менее 2 ГБ свободной памяти. Это расстраивает, когда вы просто хотите exec
простую программу и, следовательно, вам никогда не понадобится это огромное родительское адресное пространство!
vfork
не имеет этой проблемы с памятью, так как не дублирует родительское адресное пространство. Дочерний процесс действует больше как поток, в котором вы можете вызывать exec*
или _exit
, не затрагивая ваш родительский процесс.
Поскольку таблицы страниц памяти не дублируются, vfork
намного быстрее, чем fork
, и время выполнения vfork
не зависит от объема памяти, используемого родительским процессом, как указано здесь: http://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/
В ситуациях, когда производительность критична и / или ограничена память, vfork
+ exec*
может быть хорошей альтернативой fork
+ exec*
. Проблема в том, что он менее безопасен, а на странице руководства написано, что vfork
в будущем, скорее всего, устареет.
Более безопасным и более портативным решением может быть рассмотрение функции posix_spawn
, которая более высокого уровня и предлагает больше возможностей. Он безопасно использует vfork
, когда это возможно, в зависимости от параметров, которые вы передаете. Я смог успешно использовать posix_spawn
и преодолеть эту досадную «проблему двойной проверки памяти», которую мне давал fork
+ exec
.
Действительно хорошая страница на эту тему со ссылками на некоторые posix_spawn
примеры.