代码之家  ›  专栏  ›  技术社区  ›  Jason Baker

在处理C代码时,是否有任何python引用计数/垃圾收集gotchas?

  •  6
  • Jason Baker  · 技术社区  · 14 年前

    我决定创建一个 Scheme binding to libpython 所以您可以在方案程序中嵌入python。我已经能够调用Python的C API,但我还没有真正考虑内存管理。

    Mzscheme的ffi的工作方式是我可以调用一个函数,如果该函数返回一个指向 PyObject 然后我可以让它自动增加引用计数。然后,我可以注册一个终结器,当Scheme对象被垃圾收集时,它将减少引用计数。我看过 documentation for reference counting 第一眼就看不到这方面的任何问题(尽管在某些情况下可能是次优的)。我有什么地方不见了吗?

    而且,我在制作 cyclic garbage collector documentation . 在这里我需要记住什么?尤其是,我如何让python知道我有一个对某个东西的引用,这样它就不会在我还在使用它的时候收集它?

    2 回复  |  直到 12 年前
        1
  •  7
  •   Mike Graham    14 年前

    你的链接 http://docs.python.org/extending/extending.html#reference-counts 是正确的地方。文档的扩展和嵌入以及python/c api部分将解释如何使用c api。

    引用计数是使用C API的恼人部分之一。主要的方法是保持所有的内容都是正确的:根据您调用的API函数,您可能拥有或者不拥有对所获得对象的引用。要小心理解你是拥有它(因此不能忘记减量或者把它交给会偷它的东西)还是借用它(并且必须增加它来保存它,并且可能在你的功能中使用它)。涉及到这一点的最常见的错误是:1)错误地记住您是否拥有由特定函数返回的引用;2)相信您可以安全地借用一个引用的时间比实际时间长。

    您不必为循环垃圾收集器做任何特殊的事情。它只是用来修补引用计数中的一个缺陷,不需要直接访问。

        2
  •  3
  •   Virgil Dupras    14 年前

    我所知道的最大的错误是引用计数,而C API是 __del__ 事情。当你有一个借来的参考资料时,你认为你可以在不增加的情况下逃脱,因为你不会在使用该参考资料时放弃gil。但是,如果最终删除一个对象(例如,从列表中删除它),则可能会触发 埃尔德勒斯 打电话,这可能会删除你脚下借用的参考资料。非常棘手。

    如果你增加(然后减少,当然)所有借来的参考,一旦你得到他们,就不应该有任何问题。