Fab*_*ien 24 go deferred-execution
我知道你可以定义init
在任何包中调用的函数,这些函数将在之前执行main
.我用它来打开我的日志文件和我的数据库连接.
有没有办法定义程序结束时要执行的代码,因为它到达main
函数的末尾或因为它被中断了?我能想到的唯一方法是terminate
在main使用的每个包上手动调用deffered 函数,但这非常冗长且容易出错.
zzz*_*zzz 31
atexit
Go开发人员考虑了C 功能,并且采用它的想法被拒绝了.
来自golang-nuts 的相关主题之一:
Atexit在单线程,短期程序中可能有意义,但我怀疑它在长期运行的多线程服务器中占有一席之地.我已经看到许多C++程序在退出时挂起,因为它们正在运行不需要运行的全局析构函数,并且这些析构函数正在清理和释放操作系统将要回收的内存,如果只是程序的话可以进入退出系统调用.与所有那些痛苦相比,当你是一个缓冲区时需要调用Flush似乎是完全合理的,无论如何都需要正确执行长时间运行的程序.
即使忽略了这个问题,atexit引入了更多的控制线程,你必须回答像所有其他goroutine在atexit处理程序运行之前停止的问题吗?如果没有,他们如何避免干扰?如果是这样,如果一个持有处理程序需要的锁,该怎么办?等等.
我根本不想添加Atexit.
唯一完全可靠的机制是一个包装器程序,它调用真实程序并在真实程序完成时进行清理.任何语言都是如此,而不仅仅是Go.
在我有些不成熟的意见中,os.AtExit不是一个好主意.它是一种非结构化工具,会导致程序在程序退出时以不可预测的顺序发生.它会导致奇怪的情况,例如需要很长时间退出的程序,这种操作应该非常快.它还导致奇怪的函数,如C函数_exit,它或多或少意味着退出但不运行atexit函数.
也就是说,我认为对应于init函数的特殊退出函数是一个有趣的想法.它将具有os.AtExit缺少的结构(即,退出函数以与运行init函数时相反的顺序运行).
但是如果您的程序被内核杀死,退出函数将无法帮助您,或者因为您调用某些C代码而导致分段违规而导致崩溃.