В процессе, использующем много памяти, как я могу создать оболочку без разветвленной памяти ()? - PullRequest
7 голосов
/ 29 апреля 2010

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

Так есть ли способ вызвать сценарий оболочки из программы на C без дополнительных затрат памяти на fork ()?

Я рассмотрел обходные пути, такие как наличие вспомогательного процесса меньшего размера, который отвечает за создание оболочек, или наличие сценария «наблюдателя», который я сигнализирую, касаясь файла или чего-то такого, но я бы предпочел что-то более простое.

Ответы [ 5 ]

8 голосов
/ 29 апреля 2010

В некоторых реализациях UNIX вы получите vfork (часть спецификации Single UNIX), которая в точности похожа на fork, за исключением того, что она делит весь материал с родителем.

С vfork существует очень ограниченное количество вещей, которые вы можете сделать в дочернем элементе перед вызовом exec, чтобы перезаписать адресное пространство другим процессом - это в основном то, для чего была создана vfork, минимальная версия для копирования. fork для последовательности fork/exec.

6 голосов
/ 29 апреля 2010

Если ваша система имеет MMU, то обычно fork() реализуется с использованием копирования при записи, что фактически не выделяет больше памяти во время вызова fork(). Дополнительная память будет выделяться только в том случае, если вы напишите на любую страницу, которой поделился родительский процесс. exec() тогда отбрасывает эти страницы.

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

0 голосов
/ 26 июля 2010

Я вижу, что вы уже приняли ответ, но вы можете прочитать о posix_spawn и использовать его, если он доступен для вашей цели:

http://www.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html

0 голосов
/ 29 апреля 2010

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

 system("/bin/ash /scripts/bgtask");

с / scripts / bgtask, являющимся:

 /bin/ash /scripts/propertask &

Таким образом, вы удваиваете только память, используемую оболочкой, а не основной программой. Ваша основная программа загружается на время порождения двух оболочек: исходной для запуска bgtask и запускаемого им фонового клона, затем память, выделенная первой оболочкой, снова освобождается.

0 голосов
/ 29 апреля 2010

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

Тогда снова; Я не знаю, что вы на самом деле пытаетесь сделать .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...