Рассмотрите этот фрагмент кода:
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 ()
. exit ()
вызывает функции, которые вы добавили с помощью atexit ()
, и удаляет файлы, созданные с помощью tmpfile ()
. Поскольку родительский процесс действительно хочет, чтобы эти вещи выполнялись, когда он существует, вам следует вызвать _Exit ()
, который не выполняет ничего из этого.
Обратите внимание: _Exit ()
с заглавной буквы E. _exit (2)
, вероятно, не то, что вы хотите вызывать напрямую. exit (3)
и _Exit (3)
вызовут это за вас. Если у вас нет _Exit (3)
, тогда да, _exit ()
- это то, что вам нужно.
Потомок fork () всегда должен вызывать _exit ().
Вместо этого вызов exit () - хороший способ дважды очистить ожидающие буферы stdio.
execvp завершит дочерний процесс в случае успеха, поэтому вам не нужно выходить.
При ошибке execve я просто использую exit (EXIT_FAILURE);
в дочернем элементе.
Редактировать: после некоторого исследования я обнаружил, что: http://www.unixguide.net/unix/programming/1.1.3.shtml
Так что, похоже, лучше использовать _exit ( )
в дочернем элементе fork, особенно когда вы используете C ++: p
Спасибо за ваш вопрос, я кое-что узнал: D
Это зависит от желаемого поведения: man -s 3 exit
и man _exit
для получения дополнительных сведений о вашей системе. В общем, я считаю, что _exit не запускает функции, которые зарегистрированы с помощью atexit (), тогда как exit выполняет (эти функции лучше не вызывать exit - иначе вы получите рекурсию).
В общем, я бы предпочел exit вместо _exit, за исключением функций, зарегистрированных с помощью atexit, в тех случаях, когда я бы вызвал _exit, если необходимо.