vfork(2) является устаревшим (удалено из POSIX2008) и fork(2) довольно эффективно, так как он использует методы copy-on-write.
popen(3) не может закрыть все открытые файлы, потому что они не знают их и не могут знать, какие они актуальны. Представьте себе программу, которая получает socket
и передает ее файловый дескриптор в качестве аргумента для команды popen
(или просто popen("time cat /etc/issue >&9; date","r")
....). Смотрите также fcntl(2) с FD_CLOEXEC
, open(2) с O_CLOEXEC
, execve(2)
Файловые дескрипторы в рамках всей программы и процесса в масштабах отпугивают ресурсов, и это ее ответственность управлять ими правильно. Вы должны знать, какие fd-s должны быть закрыты в вашем дочернем процессе до execve
. Если вы знаете, какая программа execve
-d и какие файлы вам нужны, вы можете close
все остальные fds (или большинство из них, возможно, с for (int i=STDERR_FILENO+1; i<64; i++) (void) close(i);
) до execve
.
Если вы кодирования многоразовый библиотеки, документ его политики в отношении файловых дескрипторов (и любых других глобальных процессов в масштабах ресурсов) и, возможно, использовать FD_CLOEXEC
на любых файловых дескрипторов это получение себя (не в качестве явного аргумента или данные), например для внутреннего использования.
Похоже, вы заново изобретать p2open (тогда вы, вероятно, нужно, чтобы понять детали реализации Вашего FILE
в вашей стандартной C библиотеки, либо использовать fdopen(3) с заботой и осторожностью); вы можете найти его реализацию. Помните, что при использовании этого процесса, вероятно, должно быть около event loop (например, выше poll(2) ...), чтобы избежать потенциального тупика (с блокированием родительских и дочерних процессов при чтении).
Вы рассмотрели возможность использования какой-либо существующей инфраструктуры цикла событий (например, libevent, libev, glib от GTK и т. Д.)?
BTW Linux имеет несколько версий free software для своих C standard library. GNU libc довольно распространен, но есть musl-libc и несколько других. Изучите исходный код вашего libc.
Является ли vfork() более быстрой версией fork()? vfork() не нужно копировать таблицы страниц родительского процесса. Когда родительский процесс использует много памяти, fork() может вызвать ошибку OOM, если только ОС не настроена так, чтобы позволить overcommit памяти. – user3547691
На самом деле, и родительский процесс, использующий * лот * памяти, не должен использовать 'system' или' popen' (но код тщательно использует 'fork' и, возможно, unmapping память раньше) ... Лучше всего иметь достаточно swap которое сегодня нецелесообразно. –
Я не знаю о p2open. Мне не нужен цикл событий, потому что операции чтения и записи выполняются в отдельных потоках. – user3547691