当main()退出时调用另一个函数

10

在C语言中,当main()函数退出时调用额外的函数是否可能?

谢谢!

4个回答

23
您可以使用atexit函数注册函数,在main退出后执行。
MSDN提供了一个简洁的例子来说明如何实现。 实际上,使用atexit注册的函数按照它们的注册顺序的相反顺序执行。

2
atexit()是平台特定的奇怪行为和不可预测崩溃的常见来源。例如,OpenBSD手册建议不要使用它。我正在寻找大约2003年读过的一些关于这个主题的文章,但是找不到它们... - asveikau
@asveikau:OpenBSD建议不要使用它,因为在退出时存在竞争。如果一个单线程的OpenBSD程序天真地使用了atexit(),那么它在退出时会遭受奇怪和不可预测的崩溃吗?如果是这样的话,那就令人担忧,但我不明白为什么原则上一个平台上不合规的函数实现应该意味着你不应该在其他平台上使用它。如果你编写多线程代码,那么当然你必须关注你的平台对“隐藏”的全局数据(如atexit列表)的处理方式... - Steve Jessop
1
@Steve 我希望我能找到那些关于这个主题的旧文章,这样我就可以刷新一下它们特定推理的记忆。我似乎还记得它适用于其他系统。FWIW,我亲身经历了一些错误,因为在没有意识到处理程序在fork()上持续存在时调用了atexit(),或者在信号处理程序中调用了exit()或在锁定被保持时调用了exit(),或者如果处理程序来自一个被卸载的共享库。与信号类似,您真的应该小心处理程序来自何处以及它的功能。 - asveikau
2
我猜你可以不在意如何调用exit,或者你可以不在意如何调用atexit,但两者都不在意是不行的。大多数程序员更喜欢前者。 - Steve Jessop
@Steve:即使没有atexit,对于如何调用exit的粗心大意仍然是危险的。它不是异步信号安全的,并且由于它会刷新所有打开的文件,因此如果您违反了调用规则,它几乎肯定会给您带来问题。 - R.. GitHub STOP HELPING ICE

9

尝试使用atexit()函数:

void myfunc() {
    /* Called when the program ends */
}

int main( int arc, char *argv[] ) {
    atexit( myfunc );
    ...
    return 0;
}

2
很棒的问题和答案。只是顺便提一下,Delphi库中类似功能的滥用会导致应用程序在关闭时变得非常缓慢。

1

虽然 atexit() 是注册在进程终止时运行函数的标准方式,但GCC提供了一个析构函数function attribute*,它会在main()完成或exit()被调用时自动调用函数。

void __attribute__ ((destructor)) my_fini(void);

* GCC 特定


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接