На встроенной платформе (без раздела подкачки), у меня есть приложение, основной процесс которого занимает большую часть доступной физической памяти. Проблема состоит в том, что я хочу запустить внешний сценарий оболочки из своего приложения, но ветвление использования () требует, чтобы было достаточно памяти для 2x мой исходный процесс перед дочерним процессом (который будет в конечном счете execl самим к чему-то намного меньшему), может быть создан.
Таким образом, там какой-либо путь состоит в том, чтобы вызвать сценарий оболочки из программы C, не подвергаясь памяти наверху ветвления ()?
Я рассмотрел обходные решения, такие как наличие вторичного меньшего процесса, который ответственен за создание оболочек или наличие сценария "наблюдателя", о котором я предупреждаю путем касания файла или somesuch, но у меня очень было бы что-то более простым.
Некоторые реализации UNIX предоставят вам vfork
(часть спецификации Single UNIX), который в точности похож на fork
, за исключением того, что он разделяет весь материал с родительским.
С vfork
есть очень ограниченное количество вещей, которые вы можете сделать в дочернем элементе перед вызовом exec
для перезаписи адресного пространства другим процессом - это в основном то, что vfork
был создан для минимальной копии версии fork
для последовательности fork / exec
.
Вместо того, чтобы форкнуть ваш процесс для порождения оболочки, запустите оболочку внутри процесса (на переднем плане), а затем разветвите ее внутри оболочки.
system("/bin/ash /scripts/bgtask");
с / scripts / bgtask:
/bin/ash /scripts/propertask &
Таким образом вы удваиваете только память, используемую оболочкой, а не основной программой. Ваша основная программа занята на время создания двух оболочек: исходной для запуска bgtask и фонового клона, запущенного ею, затем память, выделенная первой оболочкой, снова освобождается.
Похоже, что разумным шагом в данном случае является перенос вашего сценария оболочки (если возможно) на C и выполнение его внутри процесса; так что вам вообще не нужно форкнуть.
Затем снова; Я не знаю, что вы на самом деле пытаетесь сделать .
Если в вашей системе есть MMU, то обычно fork ()
реализуется с использованием копирования при записи, что на самом деле не выделить больше памяти во время вызова fork ()
. Дополнительная память будет выделена только в том случае, если вы напишете на любую из страниц, совместно используемых с родительским процессом. Затем exec ()
отбрасывает эти страницы.
Если вы знаете, что у вас нет MMU, то, возможно, fork ()
действительно реализован с использованием реальной копии. Другой подход может заключаться в наличии вспомогательного процесса, который отвечает за порождение подоболочек, с которыми вы общаетесь с помощью канала.
Я вижу, что вы уже приняли ответ, но вы можете захотеть прочитать о posix_spawn
и использовать его, если он доступен на вашей цели:
http://www.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html