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

标签 go deferred-execution

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

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

最佳答案

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

来自一个相关的thread在 golang-nuts:

Russ Cox :

Atexit may make sense in single-threaded, short-lived programs, but I am skeptical that it has a place in a long-running multi-threaded server. I've seen many C++ programs that hang on exit because they're running global destructors that don't really need to run, and those destructors are cleaning up and freeing memory that would be reclaimed by the operating system anyway, if only the program could get to the exit system call. Compared to all that pain, needing to call Flush when you're one with a buffer seems entirely reasonable and is necessary anyway for correct execution of long-running programs.

Even ignoring that problem, atexit introduces even more threads of control, and you have to answer questions like do all the other goroutines stop before the atexit handlers run? If not, how do they avoid interfering? If so, what if one holds a lock that the handler needs? And on and on.

I'm not at all inclined to add Atexit.

Ian Lance Taylor :

The only fully reliable mechanism is a wrapper program that invokes the real program and does the cleanup when the real program completes. That is true in any language, not just Go.

In my somewhat unformed opinion, os.AtExit is not a great idea. It is an unstructured facility that causes stuff to happen at program exit time in an unpredictable order. It leads to weird scenarios like programs that take a long time just to exit, an operation that should be very fast. It also leads to weird functions like the C function _exit, which more or less means exit-but-don't-run-atexit-functions.

That said, I think a special exit function corresponding to the init function is an interesting idea. It would have the structure that os.AtExit lacks (namely, exit functions are run in reverse order of when init functions are run).

But exit functions won't help you if your program gets killed by the kernel, or crashes because you call some C code that gets a segmentation violation.

关于go - 在 go 中,有没有办法在程序终止时执行代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15566812/

相关文章:

c# - 延期执行会不会先调用Dispose导致失败?

javascript - 纯javascript中的延迟分配

c# - 何时使用 LINQ 的 .ToList() 或 .ToArray()

optimization - 如何优化在runtime.osyield和runtime.usleep中花费最多时间的golang程序

go - 了解 "go mod vendor"

linux - Golang 的 net.LookupHost() 是否使用 "/etc/resolv.conf"中的所有 DNS 服务器?

http - Go 中每个处理程序方法的并发连接数

docker - Kubernetes:端口转发后,我可以通过 "localhost"访问服务,但不能通过 "hostname"访问服务

c# - 为什么在使用 foreach 时不执行此 LINQ 查询?

python - 延迟库允许打包函数访问多少信息?