12

我有一个指向由 Go 结构包装的 C 类型的指针,如下所示:

type Wrapper struct {
    unmanaged *C.my_c_type
}

C 类型又具有以下功能:

my_c_type* make_c_type();
void free_c_type(my_c_type *ct);

有没有一种方法可以确保在实例完成free_c_type时调用它?Wrapper

4

1 回答 1

22

您可以使用runtime.SetFinalizer。这允许您在对象超出范围时运行清理功能。不保证运行。但是,在释放内存时,这并不重要。重要的是,对于一个长时间运行的进程,它可能会控制垃圾。

以下是文档的一些摘录(删除了整个段落):

SetFinalizer 将与 x 关联的终结器设置为 f。当垃圾收集器发现一个带有关联终结器的不可访问块时,它会清除关联并在单独的 goroutine 中运行 f(x)。这使 x 再次可访问,但现在没有关联的终结器。假设没有再次调用 SetFinalizer,下次垃圾收集器看到 x 不可达时,它会释放 x。

x 的终结器计划在 x 变得无法访问后的某个任意时间运行。无法保证终结器会在程序退出之前运行,因此它们通常仅用于在长时间运行的程序期间释放与对象关联的非内存资源。例如,当程序在不调用 Close 的情况下丢弃 os.File 时,os.File 对象可以使用终结器来关闭关联的操作系统文件描述符,但是依赖终结器来刷新内存中的 I 是错误的。 /O 缓冲区,例如 bufio.Writer,因为缓冲区不会在程序退出时被刷新。

单个 goroutine 依次运行程序的所有终结器。如果终结器必须运行很长时间,它应该通过启动一个新的 goroutine 来实现。

于 2012-08-04T22:44:37.760 回答