2013-02-12 3 views
14

Там, как представляется, два распространенных способа запуска исполнимый из C в UNIX, вызовв систему() или fork()/exec()?

system() 

и

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

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

ответ

18

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

Больше в общем, низкоуровневой вилке/Exec дает дополнительный контроль: до или между двумя операциями, вы можете chdir, открытые трубы, закрыть файл дескрипторы, настроить общую память и т.д.

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

+0

Я спросил у своего профессора, в чем разница, и он сказал, что 'system()' является API для ОС, а 'fork/exec' - это вызовы системного уровня. Это правда? Я понимаю, что API для ОС более безопасны в том смысле, что они могут содержать дополнительную проверку, а не системные вызовы. – Celeritas

+2

@Celeritas В некотором смысле (системные вызовы также являются API-интерфейсами ОС), но ваш вывод ложный, как я утверждал в ответе. 'system' не добавляет проверки; он добавляет неконтролируемую функциональность. –

0

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

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

+5

'system (" pause ");' это болезнь! Это похоже на самый неэффективный способ заставить вашу программу ждать ввода пользователем чего-либо. –

+0

@JohnZwinck это было достаточно хорошо для колледжа :), как правило, там, чтобы консоль оставалась там, когда программа собирается выйти. – Shark

+1

В следующий раз попробуйте что-нибудь вроде 'cin >> dummy;' (или scanf()). И не думайте, что работа имеет более высокие стандарты, чем школа! –

1

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

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

3

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

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

+0

, в этом случае это настраиваемый инструмент, созданный кем-то другим, поэтому мне нужно либо реорганизовать свой код в библиотеку, либо вызвать его через sys или exec, либо скопировать на кусок источника в мои собственные двоичные файлы. Это сложный выбор между скоростью выполнения ремонтопригодности. – Sparky

+1

Просто для полноты есть еще один выбор: используйте язык более высокого уровня, такой как Python, чтобы вызвать этот сторонний инструмент, а также служить «основным()» для вашего собственного кода. То есть, выставляйте свою собственную логику как библиотеку или исполняемый файл и используйте какой-то скрипт, чтобы соединить фрагменты вместе, а не выкладывать из C. Food для размышлений. –

+2

Как system(), так и popen() фактически создают два новых процесса - один для оболочки, а другой для команды, выполняемой внутри оболочки. – pelya