我正在使用一个本地linux二进制文件,它有一个相当昂贵的初始化调用,我想在应用程序启动时只执行一次。这个调用应该在内部打开一堆文件句柄,供以后使用。当我从Go调用这个昂贵的初始化C函数时,它成功地完成并正确地打开了文件,但是那些句柄只在调用C函数的过程中打开!这意味着当我从Go中对同一个库调用连续的C函数时,文件句柄不再打开,调用失败。我已经用lsof命令验证了这一点。有趣的是,当初始化调用以及对后续行为的调用组合到一个C函数中,然后从Go调用该函数时,文件将被打开并保持打开状态,从而成功地完成所有所需的功能。
是否存在某种无文档化的cgo行为,即“清理”、关闭或甚至泄漏文件句柄或其他状态资源之间的多次调用C函数从Go?如果是,这种行为可配置吗?我们无法访问这个库的源代码。
另外,我已经验证了这与线程本地存储无关。调用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).
}发布于 2015-07-13 15:49:41
好吧,这有点尴尬,但我想出来了。在调用initialize()之后,我就调用initialize(),但实际上它是延迟fmt.Println( close() )。由于延迟函数的参数是立即解析的(而不是延迟的),所以在我们可以调用任何其他行为之前调用了close函数。黄金博客清楚地解释延迟函数调用的参数解析。
https://stackoverflow.com/questions/24617523
复制相似问题