如何退出子进程 - _exit()与exit

hel*_*hod 44 c fork process

请考虑以下代码段:

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
Run Code Online (Sandbox Code Playgroud)

如果execvp返回,我该如何退出子进程?我应该使用exit()或_exit()吗?

Var*_*der 49

你一定要用_Exit(). exit()调用您添加的函数atexit()并删除使用的文件tmpfile().由于父进程实际上是在存在时希望完成这些操作的进程,因此您应该调用_Exit(),而不执行这些操作.

_Exit()使用大写字母E的 通知_exit(2)可能不是您想要直接调用的. exit(3)_Exit(3)会为你打电话.如果你没有_Exit(3),那么是的,_exit()就是你想要的.

  • 反之._Exit(3)是标准C库(ISO C99)._exit(2)是POSIX.1系统调用而不是C标准. (8认同)
  • +1您希望失败的子进程安静地退出,就像从未创建过一样. (3认同)
  • 好了,因为旧的C标准允许链接器解决不区分大小写的问题_Exit()不能是标准的库函数,因为它会与旧的_exit()冲突.抱歉. (2认同)
  • 在调用`_Exit`之后是否关闭文件等开放资源是实现定义的.您可能不希望出现此行为(关于未刷新的流).我看到的所有手册页都说`_exit`不会刷新流,所以如果文件在分叉时发生了未刷新的内容,则会更安全.`_exit`不是标准C的事实是一个有争议的问题,因为`fork`也是特定于Unix的.C标准委员会可能有特殊的理由介绍`_Exit`,但是Unix程序员没有理由将`_exit`改为`_Exit`.@VariableLengthCoder (2认同)

Jos*_*hua 15

fork()的子节点应该始终调用_exit().

相反,调用exit()是导致挂起的stdio缓冲区被刷新两次的好方法.