как выйти из дочернего процесса - _exit () против выхода - PullRequest
42 голосов
/ 25 февраля 2010

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

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 ()?

Ответы [ 5 ]

47 голосов
/ 25 февраля 2010

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

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

15 голосов
/ 25 февраля 2010

Дочерний объект fork () всегда должен вызывать _exit ().

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

3 голосов
/ 25 февраля 2010

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

В случае сбоя execve я просто использую exit(EXIT_FAILURE); у ребенка.

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

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

1 голос
/ 25 февраля 2010

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

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

0 голосов
/ 07 января 2016

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

...