garbage-collection - 有没有一种安全的方法可以使用 CGo 从 C 代码中保留对 Go 变量的引用?

标签 garbage-collection go cgo

当使用 CGo 将 C 代码与 Go 交互时,如果我在 C 端保留对 Go 变量的引用,我是否会冒着该对象被垃圾收集器释放的风险,或者 GC 是否会在C端管理的变量?

为了说明我的要求,请考虑以下示例程序:

去代码:

package main

/*
typedef struct _Foo Foo;
Foo *foo_new(void);
void foo_send(Foo *foo, int x);
int foo_recv(Foo *foo);
*/
import "C"

//export makeChannel
func makeChannel() chan int {
    return make(chan int, 1)
}

//export sendInt
func sendInt(ch chan int, x int) {
    ch <- x
}

//export recvInt
func recvInt(ch chan int) int {
    return <-ch
}

func main() {
    foo := C.foo_new()
    C.foo_send(foo, 42)
    println(C.foo_recv(foo))
}

C 代码:

#include <stdlib.h>
#include "_cgo_export.h"

struct _Foo {
    GoChan ch;
};

Foo *foo_new(void) {
    Foo *foo = malloc(sizeof(Foo));
    foo->ch = makeChannel();
    return foo;
}

void foo_send(Foo *foo, int x) {
    sendInt(foo->ch, x);
}

int foo_recv(Foo *foo) {
    return recvInt(foo->ch);
}

我是否冒着 foo->chfoo_newfoo_send 调用之间被垃圾收集器释放的风险?如果是这样,有没有办法从 C 端固定 Go 变量以防止它在我持有对它的引用时被释放?

最佳答案

根据gmp CGo example :

Garbage collection is the big problem. It is fine for the Go world to have pointers into the C world and to free those pointers when they are no longer needed. To help, the Go code can define Go objects holding the C pointers and use runtime.SetFinalizer on those Go objects.

It is much more difficult for the C world to have pointers into the Go world, because the Go garbage collector is unaware of the memory allocated by C. The most important consideration is not to constrain future implementations, so the rule is that Go code can hand a Go pointer to C code but must separately arrange for Go to hang on to a reference to the pointer until C is done with it.

所以我不确定您是否可以从 C 端固定变量,但您可以使用 runtime.SetFinalizer 从 Go 端控制变量的垃圾回收。功能。

希望对您有所帮助。

关于garbage-collection - 有没有一种安全的方法可以使用 CGo 从 C 代码中保留对 Go 变量的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20363072/

相关文章:

http - 如何获得第一个 HTTP(重定向)响应?

java - 如何让JVM释放内存给OS

c# - c# 中最简单的 IDisposable 模式是什么?

java - 为什么 WeakHashMap 在 GC 后对值有强引用?

mysql - 如何使用golang从mysql中获取多个列

arrays - slice : Trouble appending to a slice in a struct

linux - cgo 交叉编译找不到库

Go 语言/CGO : Problems calling Mach API host_statistics() from Go

c - 在 C 语言中使用 Go slice

java - Activity 内部出现奇怪的 NullPointerException