我们应该在子进程中使用退出还是返回

时间:2019-05-11 12:24:10

标签: c++ c linux unix fork

说我已经使用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。据我了解,_exitexit不会自动调用析构函数,因此在子进程中调用return而不是exit更好吗?还是因为我见过的所有示例都是C而不是C ++,所以它们不必担心析构函数?

4 个答案:

答案 0 :(得分:0)

如果您正在寻找子进程的退出代码,则可以使用return,以表示该进程已正确运行/未执行。与在程序中使用主要功能相同。否则,只需使用exit即可停止该进程继续运行。

答案 1 :(得分:0)

在任何情况下都应避免使用退出命令,除非终止程序的执行。对于其他任何事情,我都会使用return。

答案 2 :(得分:-1)

fork将复制整个过程,这不等同于使用新的main函数启动线程。 返回将简单地从当前函数返回,子进程的执行将继续在封闭函数中进行。

因此,在您的摘要中,您必须终止该孩子,否则它将“逃跑”。您可以通过调用exit()std::terminate()来做到这一点。在这两种情况下都不会调用析构函数。不要混用两种不同的语言。

如果您确实需要在子级中调用析构函数,请抛出异常并在main中捕获它。这样可以正确展开堆栈。

答案 3 :(得分:-1)

您可以使用_exitexit,但不应使用return。派生孩子时,保留整个调用堆栈作为派生孩子的一部分。因此,如果您使用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;
    }
}

您最终可能会致电fg或使用return做其他工作,这绝对是不希望的。

如果您调用_exit,则不会调用在atexit中注册的函数。这是在线程环境中要做的正确的事情。如果您不在线程环境中工作,并且没有向atexit注册任何处理程序,则它们在功能上应等效。

如果要在子进程中调用析构函数,请将子进程代码放入其自己的函数中,并让其变量超出范围时自动销毁它们。 exit不会为您破坏对象,这很好,因为通常您不想破坏子流程中在父流程中创建的对象。