posix_spawn
, вероятно, является предпочтительным решением в наши дни.
До этого для этого использовался fork()
, а затем execXX()
(где execXX
— одна из функций семейства exec
, включая execl
, execlp
, execle
, execv
, execvp
и execvpe
). В настоящее время в библиотеке GNU C, по крайней мере, для Linux, posix_spawn
в любом случае реализуется через fork/exec; В Linux нет системного вызова posix_spawn
.
Вы должны использовать fork()
(или vfork()
) для запуска отдельного процесса, который будет клоном родителя. Как в дочернем, так и в родительском процессе выполнение продолжается, но fork
возвращает другое значение в любом случае, что позволяет различать их. Затем вы можете использовать одну из execXX()
функций внутри дочернего процесса.
Однако обратите внимание на эту проблему — текст, заимствованный из одного из моих сообщений в блоге (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):
Кажется, не существует простого, совместимого со стандартами способа (или даже вообще переносимого способа) для параллельного выполнения другого процесса и уверенности в том, что вызов exec() прошел успешно. Проблема в том, что после того, как вы выполнили fork()d, а затем успешно выполнили exec(), вы не можете связаться с родительским процессом, чтобы сообщить об успешном выполнении exec(). Если exec() терпит неудачу, вы можете общаться с родителем (например, через сигнал), но вы не можете сообщить об успехе - единственный способ, которым родитель может быть уверен в успехе exec(), - это ждать() для ребенка процесс для завершения (и убедитесь, что нет индикации сбоя) и, конечно же, это не параллельное выполнение.
то есть, если execXX()
завершается успешно, вы больше не имеете контроля, поэтому не можете сигнализировать об успехе исходному (родительскому) процессу.
Возможное решение этой проблемы, если это проблема в вашем случае:
[...] используйте pipe() для создания канала, установите конец вывода как close-on-exec, затем fork() (или vfork()), exec() и напишите что-нибудь (возможно, errno) в pipe в случае сбоя exec() (до вызова _exit()). Родительский процесс может читать из канала и получит немедленный конец ввода, если exec() завершится успешно, или некоторые данные, если exec() завершится ошибкой.
(Обратите внимание, что это решение может вызвать инверсию приоритета, если дочерний процесс выполняется с более низким приоритетом, чем родительский, и родительский процесс ожидает выходных данных от него).
Существует также posix_spawn
, как упоминалось выше и в других ответах, но он не решает проблему обнаружения сбоя при выполнении дочернего исполняемого файла, поскольку он в любом случае часто реализуется с точки зрения fork/exec и может вернуть успех до сбоя этапа exec()
.
person
davmac
schedule
04.05.2011