我们应该在子进程中使用 exit 还是 return
Should we use exit or return in child process
说我用fork
创建了一个子进程。这是一个例子:
pid_t pid=fork();
if (pid==0) /* child */
{
// do something
exit(0); // _exit, exit or return????
}
else /* parrent */
{
wait(nullptr);
return 0;
}
我见过很多 fork
的例子。其中一些使用 _exit
来终止子进程以避免刷新 I/O 缓冲区,其他人使用 exit
来终止子进程。但他们中没有人使用 return
。据我了解,_exit
和 exit
不会自动调用析构函数,所以在子进程中调用 return
而不是 exit
更好吗?或者因为我见过的所有例子都是 C,而不是 C++,所以他们不需要担心析构函数?
如果您正在寻找子进程的退出代码,您可以使用 return,只是说进程 运行 并执行 correctly/not。与您在程序中对主要功能所做的相同。否则,只需使用 exit 停止进程 运行。
fork
会复制整个过程,它不等同于用新的主函数启动一个线程。
返回将简单地从当前函数 return 并且子函数的执行将在封闭函数中继续。
因此在您的代码片段中,您必须终止子进程,否则它将 "escape"。您可以通过调用 exit()
或 std::terminate()
来实现。在这两种情况下都没有调用析构函数。不要混用两种不同的语言。
如果你真的需要在子进程中调用析构函数,抛出异常并在main中捕获它。这将正确展开堆栈。
您可以使用 _exit
或 exit
,但不应使用 return
。当您分叉 child 时,您保留了整个调用堆栈作为分叉 child 的一部分。因此,如果您使用 return
,您最终会返回整个程序,可能会继续执行其他任务,这几乎肯定不是您想要的。
例如,如果您有这样的片段:
int get_value()
{
pid_t pid;
if (!(pid = fork())) {
int x = 0;
// do something with x.
exit(x);
}
else {
int status;
wait(&status);
return status;
}
}
int main()
{
int value = get_value();
switch (get_value()) {
case 0:
// call f
break;
case 255 << 8:
// call g
break;
}
}
您最终可能会调用 f
或 g
或使用 return
进行其他工作,这绝对不是您想要的。
如果您调用 _exit
,则不会调用使用 atexit
注册的函数。在线程环境中这是正确的做法。如果您不在线程环境中工作,并且您没有在 atexit
注册任何处理程序,那么它们在功能上应该是等效的。
如果要调用 child 进程中的析构函数,请将 child 进程代码放在它自己的函数中,并让它的变量在超出范围时自动销毁。 exit
不会为您销毁 objects,这很好,因为通常您不想在 child 进程中销毁在 parent 进程中创建的 objects。
Exit命令在任何情况下都应避免使用,除非结束程序的执行。对于其他任何事情,我会使用 return.
说我用fork
创建了一个子进程。这是一个例子:
pid_t pid=fork();
if (pid==0) /* child */
{
// do something
exit(0); // _exit, exit or return????
}
else /* parrent */
{
wait(nullptr);
return 0;
}
我见过很多 fork
的例子。其中一些使用 _exit
来终止子进程以避免刷新 I/O 缓冲区,其他人使用 exit
来终止子进程。但他们中没有人使用 return
。据我了解,_exit
和 exit
不会自动调用析构函数,所以在子进程中调用 return
而不是 exit
更好吗?或者因为我见过的所有例子都是 C,而不是 C++,所以他们不需要担心析构函数?
如果您正在寻找子进程的退出代码,您可以使用 return,只是说进程 运行 并执行 correctly/not。与您在程序中对主要功能所做的相同。否则,只需使用 exit 停止进程 运行。
fork
会复制整个过程,它不等同于用新的主函数启动一个线程。
返回将简单地从当前函数 return 并且子函数的执行将在封闭函数中继续。
因此在您的代码片段中,您必须终止子进程,否则它将 "escape"。您可以通过调用 exit()
或 std::terminate()
来实现。在这两种情况下都没有调用析构函数。不要混用两种不同的语言。
如果你真的需要在子进程中调用析构函数,抛出异常并在main中捕获它。这将正确展开堆栈。
您可以使用 _exit
或 exit
,但不应使用 return
。当您分叉 child 时,您保留了整个调用堆栈作为分叉 child 的一部分。因此,如果您使用 return
,您最终会返回整个程序,可能会继续执行其他任务,这几乎肯定不是您想要的。
例如,如果您有这样的片段:
int get_value()
{
pid_t pid;
if (!(pid = fork())) {
int x = 0;
// do something with x.
exit(x);
}
else {
int status;
wait(&status);
return status;
}
}
int main()
{
int value = get_value();
switch (get_value()) {
case 0:
// call f
break;
case 255 << 8:
// call g
break;
}
}
您最终可能会调用 f
或 g
或使用 return
进行其他工作,这绝对不是您想要的。
如果您调用 _exit
,则不会调用使用 atexit
注册的函数。在线程环境中这是正确的做法。如果您不在线程环境中工作,并且您没有在 atexit
注册任何处理程序,那么它们在功能上应该是等效的。
如果要调用 child 进程中的析构函数,请将 child 进程代码放在它自己的函数中,并让它的变量在超出范围时自动销毁。 exit
不会为您销毁 objects,这很好,因为通常您不想在 child 进程中销毁在 parent 进程中创建的 objects。
Exit命令在任何情况下都应避免使用,除非结束程序的执行。对于其他任何事情,我会使用 return.