To system() или fork()/exec()? - программирование
Подтвердить что ты не робот

To system() или fork()/exec()?

Кажется, существуют два общих способа запуска внешнего исполняемого файла из C в unix,

system()

и

pid = fork()
switch(pid)
//switch statement based on return value of pid, 
//one branch of which will include and exec() command

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

4b9b3361

Ответ 1

system выполняет командный интерпретатор, то есть оболочку, которая (a) медленнее, чем прямой fork/exec, (b) может вести себя по-разному в разных системах и (c) является потенциальной угрозой безопасности, если вы пройдете это строка из ненадежного источника. Кроме того, system ожидает, что дочерний процесс завершит работу, в то время как вы можете запустить его параллельно с родительским процессом.

В общем случае низкоуровневый fork/exec дает вам дополнительный контроль: до или между двумя операциями вы можете захотеть chdir, открыть каналы, закрыть дескрипторы файлов, настроить общую память и т.д.

(В разных системах я не имею в виду Windows vs. Unix (поскольку Windows даже не имеет fork): я говорю о Red Hat Linux vs. Ubuntu. Первая использует Bash для выполнения того, что передается до system, последняя - легкая POSIX-совместимая оболочка.)

Ответ 2

fork() создает новый процесс. Если вам не нужно это делать, просто используйте system() (или popen()). Возможно, вам понадобится второй процесс для достижения parallelism, или для более тонкого контроля над заданием, но часто вам просто все равно, если задание должно быть синхронным.

С другой стороны, я считаю, что 95% использования system() не нужны или как-то лучше сделать другим способом (например, с использованием zlib вместо system("gzip")). Поэтому, возможно, лучший ответ - не использовать ни одного!

Ответ 3

Переход через system() дополнительно вызывает процесс оболочки, который может быть не таким, каким вы хотите.

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

Ответ 4

system() выберет команду и выполнит ее, как только пользователь набрал бы ее. я в основном видел это как system("pause"); system("cls");

Но если вам нужно управлять дочерним процессом, вы хотите использовать fork.