GoLang CGO文件句柄

时间:2014-07-07 18:40:53

标签: go cgo

我正在使用本机linux C二进制文件,它有一个相当昂贵的初始化调用,我想在应用程序启动时执行一次。此调用应在内部打开一堆文件句柄以供以后使用。当我从Go调用这个昂贵的初始化C函数时,它成功完成并正确打开文件,但这些句柄仅在调用C函数期间打开!这意味着当我从Go对同一个库调用连续的C函数时,文件句柄不再打开,调用失败。我已经使用lsof命令验证了这一点。有趣的是,当初始化调用以及对后续行为的调用组成一个C函数然后从Go调用时,文件将被打开并保持打开状态,从而成功完成所有所需的功能。

在Go的多个C函数调用之间是否有某种未记录的cgo行为“清理”,关闭甚至泄漏文件句柄或其他有状态资源?如果是这样,这种行为是否可配置?我们无权访问此库的源代码。

另外,我已经确认这与线程本地存储无关。调用runtime.LockOSThread()没有任何效果,我们已经验证文件在控制权从C返回到调用Go代码后关闭。

以下是我想写的Go代码示例:

// Go code:

func main() {
    C.Initialize()
    C.do_stuff() // internal state is already cleaned up! This call fails as a result. :(
}

这是一个C函数的示例,它一次调用初始化和行为。这个“包装”函数是从Go:

调用的
// C code:

void DoEverything(void)
{
    Initialize();
    do_stuff(); // succeeds because all internal state is intact (not cleaned up).
}

1 个答案:

答案 0 :(得分:0)

好的,这有点令人尴尬,但我想通了。在调用initialize()之后,我调用defer close(),但它实际上是延迟fmt.Println(close())。因为延迟函数的参数被立即解析(而不是延迟),所以在我们调用任何其他行为之前调用close函数。 golang博客clearly explains argument resolution to deferred function calls