在go中,有没有办法在终止程序时执行代码?

时间:2013-03-22 09:27:09

标签: go deferred-execution

我知道你可以在任何包中定义名为init的函数,这些函数将在main之前执行。我用它来打开我的日志文件和我的数据库连接。

有没有办法定义程序结​​束时要执行的代码,因为它到达main函数的末尾或因为它被中断了?我能想到的唯一方法是在main使用的每个包上手动调用一个deffered terminate函数,但这非常冗长且容易出错。

3 个答案:

答案 0 :(得分:29)

Go开发人员考虑了C atexit功能,并且拒绝了采用它的想法。

来自golang-nuts的相关thread之一:

Russ Cox

  

Atexit可能在单线程,短命中有意义   程序,但我怀疑它在一个地方有一席之地   长时间运行的多线程服务器。   我看过许多C ++程序在退出时挂起,因为   他们正在运行不需要的全局析构函数   运行,那些析构函数正在清理和释放   可由操作系统回收的内存   无论如何,如果只有程序可以进入退出系统调用。   与所有那些痛苦相比,当你需要时,需要打电话给Flush   一个有缓冲区似乎是完全合理的   无论如何,正确执行长时间运行是必要的   程序

     

即使忽略了这个问题,atexit也会引入更多   控制线程,你必须回答类似的问题   所有其他goroutines在atexit处理程序之前停止   跑?如果没有,他们如何避免干扰?如果是这样,如果   一个持有处理程序需要的锁?等等。

     

我根本不想添加Atexit。

Ian Lance Taylor

  

唯一完全可靠的机制是一个调用它的包装器程序   真正的程序,并在真正的程序完成时进行清理。那   任何语言都是如此,而不仅仅是Go。

     

在我有些不成熟的意见中,os.AtExit不是一个好主意。它是   一个非结构化的工具,导致程序退出时发生的事情   时间以不可预测的顺序。它导致了奇怪的情况,如   需要很长时间才能退出的程序,应该是一个操作   非常快。它还导致奇怪的函数,如C函数_exit,   这或多或少意味着退出但不运行atexit功能。

     

那说,我认为一个特殊的退出函数对应于init   功能是一个有趣的想法。它将具有这样的结构   os.AtExit缺少(即,退出函数以与时间相反的顺序运行   init函数运行)。

     

但如果你的程序被你的程序杀死,退出函数将无法帮助你   内核或崩溃,因为你调用一些获得分段的C代码   违反。

答案 1 :(得分:2)

如果在阅读了所有这些内容(并且可能会看到this)后,您仍然需要atexit - 请查看https://github.com/tebeka/atexit:)

答案 2 :(得分:-3)

一般来说,我同意jnml的回答。但是,如果您仍想这样做,可以在main()函数中使用defer,如下所示:http://play.golang.org/p/aUdFXHtFOM