默认情况下,Go 中哪些对象是最终确定的?它有哪些陷阱?

发布于 2024-12-22 06:36:35 字数 226 浏览 4 评论 0原文

函数 runtime.SetFinalizer(x, f 接口{})将与 x 关联的终结器设置为 f

什么样的对象是默认终结的?

默认情况下最终确定这些对象会导致哪些意外陷阱?

The function runtime.SetFinalizer(x, f interface{}) sets the finalizer associated with x to f.

What kind of objects are finalized by default?

What are some of the unintended pitfalls caused by having those objects finalized by default?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愛上了 2024-12-29 06:36:35

默认情况下最终确定以下对象:

Go 标准库不会对上述以外的对象类型设置终结器。

似乎只有一个潜在问题可能会导致实际程序出现问题:当 os.File 完成时,它将调用操作系统来关闭文件描述符。如果 os.File 是通过调用函数 os.NewFile(fd int, name string) *File 创建的,并且文件描述符也被另一个(不同的)使用os.File,则垃圾收集其中一个文件对象将使另一个文件对象无法使用。例如:

package main

import (
    "fmt"
    "os"
    "runtime"
)

func open() {
    os.NewFile(1, "stdout")
}

func main() {
    open()

    // Force finalization of unreachable objects
    _ = make([]byte, 1e7)
    runtime.GC()

    _, err := fmt.Println("some text") // Print something via os.Stdout
    if err != nil {
        fmt.Fprintln(os.Stderr, "could not print the text")
    }
}

打印:

could not print the text

The following objects are finalized by default:

  • os.File: The file is automatically closed when the object is garbage collected.

  • os.Process: Finalization will release any resources associated with the process. On Unix, this is a no-operation. On Windows, it closes the handle associated with the process.

  • On Windows, it appears that package net can automatically close a network connection.

The Go standard library is not setting a finalizer on object kinds other than the ones mentioned above.

There seems to be only one potential issue that may cause problems in actual programs: When an os.File is finalized, it will make a call to the OS to close the file descriptor. In case the os.File has been created by calling function os.NewFile(fd int, name string) *File and the file descriptor is also used by another (different) os.File, then garbage collecting either one of the file objects will render the other file object unusable. For example:

package main

import (
    "fmt"
    "os"
    "runtime"
)

func open() {
    os.NewFile(1, "stdout")
}

func main() {
    open()

    // Force finalization of unreachable objects
    _ = make([]byte, 1e7)
    runtime.GC()

    _, err := fmt.Println("some text") // Print something via os.Stdout
    if err != nil {
        fmt.Fprintln(os.Stderr, "could not print the text")
    }
}

prints:

could not print the text
终陌 2024-12-29 06:36:35

只需跳转到 os.NewFile 的源代码:

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
    fdi := int(fd)
    if fdi < 0 {
        return nil
    }
    f := &File{&file{fd: fdi, name: name}}
    runtime.SetFinalizer(f.file, (*file).close)  // <<<<<<<<<<<<<<
    return f
}
  • 当 go 运行 GC 时,它将在该对象上运行 Finalizers 绑定。
  • 当您打开一个新文件时,go 库将为您在返回的对象上绑定一个 Finalizer。
  • 当您不确定 GC 将对该对象执行什么操作时,请跳转到源代码并检查库是否已在该对象上设置了一些终结器。

Just jump into the os.NewFile's source code:

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
    fdi := int(fd)
    if fdi < 0 {
        return nil
    }
    f := &File{&file{fd: fdi, name: name}}
    runtime.SetFinalizer(f.file, (*file).close)  // <<<<<<<<<<<<<<
    return f
}
  • When go runs GC, it will run Finalizers bind on that object.
  • When you open a new file, the go library will bind a Finalizer on that returned object for you.
  • When you are not sure what the GC will do to that object, jump to source code and check whether the library has set some finalizers on that object.
沉默的熊 2024-12-29 06:36:35

“默认情况下,什么类型的对象是最终确定的?”
在 IMO 中,Go 中的任何内容都不是默认最终确定的。

“默认情况下完成这些对象会导致哪些意外陷阱?”
如上所述:没有。

"What kind of objects are finalized by default?"
Nothing in Go is IMO finalized by default.

"What are some of the unintended pitfalls caused by having those objects finalized by default?"
As per above: none.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文