我需要使用defer来释放使用C库手动创建的分配,但我也需要在某个时刻使用非0状态的os.Exit.棘手的是os.Exit会跳过任何延迟的指令:

package main

import "fmt"
import "os"

func main() {

    // `defer`s will _not_ be run when using `os.Exit`, so
    // this `fmt.Println` will never be called.
    defer fmt.Println("!")
    // sometimes ones might use defer to do critical operations
    // like close a database, remove a lock or free memory

    // Exit with status code.
    os.Exit(3)
}

playground :https://gobyexample.com/exit个playground 中有http://play.golang.org/p/CDiAh9SXRM个被盗

那么,如何退出一个Go程序来兑现声明的defer个呼叫呢?除了os.Exit,还有其他 Select 吗?

推荐答案

runtime.Goexit()是实现这一目标的简单方法.

goexit终止调用它的goroutine.其他猩猩不会受到影响.Goexit runs all deferred calls before terminating the goroutine.因为Goexit不是死机,所以这些延迟函数中的任何恢复调用都将返回nil.

然而:

从主goroutine调用Goexit将终止该goroutine,而不返回func main.由于func main尚未返回,程序将继续执行其他goroutine.如果所有其他goroutine退出,程序就会崩溃.

因此,如果你从主goroutine中调用它,在main的顶部,你需要添加

defer os.Exit(0)

在下面,您可能想要添加一些其他defer条语句,以通知其他Goroutine停止并清理.

Go相关问答推荐

map 中的多个函数类型,Golang

如何在v2 Go SDK中使用KeyConditionExpression查询AWS DynamoDb?

如何解析Go-Gin多部分请求中的 struct 切片

无法读取postman 中的表单数据

这种合并排序的实现有什么问题?

从 ApiGateway 中的 lambda Go 返回 Json

Go 切片容量增长率

Go 信号处理程序不处理终端窗口关闭

Golang 通过接口反映/迭代{}

Go:从 ssl 证书中获取 'subject/unstructeredName' 的值

如何使用 Docker 引擎 SDK 和 Golang 运行 docker 挂载卷

如何将一片 map 转换为一片具有不同属性的 struct

如何使用 go-playground/validator 编写 snake case 绑定标签?

如何使用 Status 字段创建 Kubernetes 对象?

Golang 数据库/sql 与 SetMaxOpenConns 挂起

Go GCP 同时模拟两个服务帐户

Unescape 在 rss 中两次逃脱了标题

Golang API 的 HTTPS

为什么 go-cmp Equal() 说 struct 不是完全相等的,即使所有字段都非常相等?

泛型:对具有返回自身的函数的类型的约束