C++中exit和kill的区别

Difference between exit and kill in C++

我已经编写了一个信号处理程序来处理 SIG,如果收到太多信号,我想终止该进程。那么,下面哪个代码更好,或者我应该同时使用它们?

  1. exit(-1); // or some other exit code
  2. kill(getpid(), SIGKILL);

我会推荐 exit(1)

通常情况下,如果可能的话,应用程序会希望优雅地终止。 SIGKILL 是您的进程的即时死亡 - 例如,您的退出处理程序不会被调用。但在您的情况下,您还必须调用 getpid 以及 kill 本身。 exit 立即 启动正常退出过程。这是满足您需求的正确选择。

一般来说,体系结构很少有理由使用 SIGKILL。有这么多信号(POSIX 中的 http://man7.org/linux/man-pages/man7/signal.7.html,你有 SIGINT、SIGTERM,...),重申一下,如果你没有理由 优雅地死去能够。

Difference between exit and kill in C++

一个区别是 kill 函数没有在 C++ 标准库中指定。它仅在 POSIX 中指定。 exit 是标准 C++。

另一个区别是kill(getpid(), SIGKILL)会导致操作系统强行终止进程。 exit 改为执行清理(通过调用 atexit 回调和刷新流等)并自愿终止执行。

So, which of the following code is better, or should I use them both?

取决于用例,但通常 exit 更明智,因为人们通常需要它提供的清理。

你可能两个都不想要,但你想要的更接近 exit 而不是 kill

kill 是其他东西从外面进来,强行破坏一个进程。 exit 是进程本身决定退出执行。后者通常更可取。

至于为什么 exit 也不是正确的答案:大多数 C++ 代码都依赖析构函数在您退出作用域时清理对象。如果您调用 exit,这通常不会发生——您调用 exit,它会退出到 OS,并且在这期间不会调用任何析构函数(除了使用 onexit 注册的东西)。

相反,您通常希望抛出通常只在 main 中捕获的异常,并在捕获时优雅地退出:

int main() { 
    try {
        do_stuff();
    }
    catch(time_to_die const &) {
    }
}

这种情况的优点是,当您执行 throw time_to_die; 时,它会自动展开堆栈,同时为所有本地对象执行析构函数。当它返回 main 时,您会正常退出,所有析构函数都已执行,因此(假设正确使用 RAII)您的所有文件、网络连接、数据库连接等都已按预期关闭,任何缓存都已刷新,等等,这样您就可以顺利退出。

简短总结:根据经验,C++ 代码永远不应调用 exit。如果你的代码完全卡在了一个crack中,你想马上退出,你想调用abort。如果你想要一个半正常的退出,通过抛出一个异常让你回到 main 来做到这一点,这样你就可以清理一切并优雅地退出。