Является ли последовательность unix fork exec действительно такой дорогой, как кажется? - PullRequest
12 голосов
/ 03 декабря 2011

Я читаю около fork и exec для экзамена, и моя книга говорит, что всякий раз, когда это необходимо для запуска нового (другого) процесса в Unix-системах, вы должны форкнуть текущий процесс с последующим execve.

Однако в нем также говорится, что всякий раз, когда вызывается fork, весь образ памяти родителя копируется в новый процесс.

Тогда мой вопрос: что если выУ вас есть процесс с действительно большим образом памяти, и вы просто хотите запустить новый процесс?Разве это не пустая трата ресурсов, чтобы скопировать все данные из родительского процесса, если вы собираетесь немедленно заменить их?

Ответы [ 3 ]

6 голосов
/ 03 декабря 2011

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

Это означает, что для разветвления от большого процесса в системах, которые не допускают чрезмерной загрузки памяти, память должна быть доступна. Таким образом, если у вас есть процесс разветвления 8 ГБ, то по крайней мере в течение короткого периода времени должно быть доступно 16 ГБ.

См. Также vfork и posix_spawn для других решений.

2 голосов
/ 20 января 2015

Некоторые системы, которые являются либо очень старыми (ранний Unix), либо очень специальными (mmu-linux) или verfy crappy (windows через cygwin), должны делать полную копию всех страниц («каждый байт») на fork так что потенциал есть.

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

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

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

Чтобы привести некоторые реальные цифры, в моей системе GNU / Linux я могу выполнить команду выхода + 1340 раз в секунду из процесса с 20 МБ, но только с 235 раз / с в процессе с 2000 МБ. В обоих случаях это быстрее, чем vfork + execve, что несколько не интуитивно понятно, потому что многие думают, что «форк быстр» и «execve должен быть медленным».

1 голос
/ 03 декабря 2011

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

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

Я думаю, вы можете найти это в Расширенное программирование в UNIX

...