【发布时间】:2016-06-02 10:01:13
【问题描述】:
今天早上发布了 Go 1.7 beta 1,这里是 the release notes draft of Go 1.7。一个新函数KeepAlive 被添加到包runtime 中。 The doc of runtime.KeepAlive已经举了一个例子:
type File struct { d int }
d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
// ... do something if err != nil ...
p := &FILE{d}
runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
var buf [10]byte
n, err := syscall.Read(p.d, buf[:])
// Ensure p is not finalized until Read returns.
runtime.KeepAlive(p)
// No more uses of p after this point.
The doc of runtime.SetFinalizer也给出了关于runtime.KeepAlive的解释:
例如,如果 p 指向一个包含文件描述符的结构 d,并且 p 有一个关闭该文件描述符的终结器,如果 在函数中最后一次使用 p 是调用 syscall.Write(p.d, buf, size),那么 p 可能一进入程序就无法到达 系统调用。写。终结器可能会在那个时候运行,关闭 p.d, 导致 syscall.Write 失败,因为它正在写入已关闭的文件 描述符(或者,更糟糕的是,打开一个完全不同的文件描述符 由不同的 goroutine)。为避免此问题,请致电 runtime.KeepAlive(p) 在调用 syscall.Write 之后。
让我困惑的是变量p还没有离开它的生命范围,为什么会无法访问?这是否意味着,只要在下面的代码中没有使用变量,无论它是否在其生命范围内,它都将无法访问?
【问题讨论】:
标签: go garbage-collection