как выйти из дочернего процесса - _exit() по сравнению с выходом

Рассмотрим этот фрагмент кода:

pid_t cpid = fork();

if (cpid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
}

if (cpid == 0) { // in child
    execvp(argv[1], argv + 1);
    perror("execvp");
    _exit(EXIT_FAILURE);
}

// in parent

Как мне выйти из дочернего процесса, если execvp вернется? Должен ли я использовать exit() или _exit()?


person helpermethod    schedule 24.02.2010    source источник


Ответы (5)


Вы обязательно должны использовать _Exit(). exit() вызывает функции, которые вы добавили с помощью atexit(), и удаляет файлы, созданные с помощью tmpfile(). Поскольку родительский процесс действительно хочет, чтобы эти вещи были выполнены, когда он существует, вы должны вызвать _Exit(), который не делает ничего из этого.

Обратите внимание, что _Exit() с большой буквы E. _exit(2), вероятно, не то, что вы хотите называть напрямую. exit(3) и _Exit(3) позвонят вам. Если у вас нет _Exit(3), то да, _exit() — это то, что вы хотели.

person Variable Length Coder    schedule 24.02.2010
comment
+1 Вы хотите, чтобы неудавшийся дочерний процесс тихо завершился, как если бы он никогда не создавался. - person John Kugelman; 25.02.2010
comment
Что ж, поскольку старый стандарт C позволял компоновщику разрешать нечувствительные к регистру символы, _Exit() не может быть стандартной библиотечной функцией, так как это будет конфликтовать со старым _exit(). Прости. - person Joshua; 25.02.2010
comment
Напротив. _Exit(3) — это стандартная библиотека C (ISO C99). _exit(2) — это системный вызов POSIX.1, а не стандарт C. - person Variable Length Coder; 25.02.2010
comment
Закрываются ли открытые ресурсы, такие как файлы, после вызова _Exit, определяется реализацией. Вы, вероятно, не хотите такого поведения (относительно несбрасываемых потоков). Все справочные страницы, которые я видел, говорят, что _exit не сбрасывает потоки, поэтому безопаснее, если файл имеет несброшенное содержимое, когда происходит разветвление. Тот факт, что _exit не является стандартным C, является спорным вопросом, поскольку fork также специфичен для Unix. У комитета по стандарту C могут быть особые причины для введения _Exit, но у программистов Unix нет никаких причин менять _exit на _Exit. @VariableLengthCoder - person Yongwei Wu; 13.12.2017

Потомок fork() всегда должен вызывать _exit().

Вызов exit() вместо этого является хорошим способом вызвать двойную очистку ожидающих буферов stdio.

person Joshua    schedule 24.02.2010
comment
exec не возвращает результат, за исключением ошибки, при которой вы вызываете _exit. - person Joshua; 14.02.2014

execvp выйдет из дочернего процесса в случае успеха, поэтому вам не нужно выходить.

При ошибке execve я просто использую exit(EXIT_FAILURE); в дочернем элементе.

Изменить: я обнаружил, что после некоторых исследований: http://www.unixguide.net/unix/programming/1.1.3.shtml

Так что, похоже, лучше использовать _exit() в дочернем форке, особенно когда вы работаете на C++: p Спасибо за ваш вопрос, я кое-что узнал: D

person Nicolas Guillaume    schedule 24.02.2010

Это зависит от желаемого поведения: man -s 3 exit и man _exit для более подробной информации о вашей системе. В общем, я считаю, что _exit не запускает функции, зарегистрированные с помощью atexit(), тогда как exit делает (эти функции лучше не вызывать exit, иначе вы получите рекурсию).

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

person jabbie    schedule 24.02.2010

exit() — это функция ANSI-C, поэтому она не зависит от операционной системы. Он закрывает все стандартные функции ANSI-C. _exit() вызывается exit() для закрытия функций, зависящих от операционной системы, поскольку exit() ничего о них не знает. (exit не зависит от операционной системы)

person ImanKh    schedule 07.01.2016
comment
_exit() — это неверная функция ядра Linux, см. pubs.opengroup.org /onlinepubs/9699919799/functions/_Exit.html - person Dr. Jan-Philip Gehrcke; 06.10.2016
comment
В этом вы правы, но в остальном мой комментарий верен. См. «Системное программирование Unix» Дэвида Карри, стр. 291. - person ImanKh; 06.10.2016