Cコードを扱う際に、Pythonリファレンスカウント/ガベージコレクションのゴトカスはありますか?
-
05-10-2019 - |
質問
ちょうどそれのために、私は Libpythonへのスキームバインド したがって、スキームプログラムにPythonを埋め込むことができます。私はすでにPythonのC APIを呼び出すことができますが、メモリ管理について本当に考えていませんでした。
mzschemeのFFIが機能する方法は、私が関数を呼び出すことができるということであり、その関数がポインターを返す場合です PyObject
, 、その後、参照カウントを自動的に増分することができます。次に、スキームオブジェクトがガベージを収集したときに参照カウントを減らすファイナイザーを登録できます。私は見ました 参照カウントのためのドキュメント, 、そして、一見してこれに問題は見られません(ただし、場合によっては最適ではない場合があります)。私が足りないゴシュチャはありますか?
また、私は頭や尾を作るのに苦労しています 周期的なゴミコレクターのドキュメント. 。ここで何を心に留めておく必要がありますか?特に、Pythonに何かへの参照があることをどのように認識させることができます。
解決
へのあなたのリンク http://docs.python.org/extending/extending.html#reference-counts 正しい場所です。ドキュメントの拡張および埋め込みおよびPython/C APIセクションは、C APIの使用方法を説明するものです。
参照カウントは、C APIを使用する際の迷惑な部分の1つです。メインのゴッチャは、すべてをまっすぐに保つことです。呼び出すAPI関数に応じて、取得したオブジェクトへの参照を所有している場合と所有していない場合があります。あなたがそれを所有しているかどうかを理解するように注意してください(したがって、それを除去することを忘れたり、それを盗むものに与えることを忘れることはできません)、またはそれを借りている(そしてそれを保持し、おそらくあなたの機能中にそれを使用するためにそれを挿入する必要があります)。これを含む最も一般的なバグは、1)特定の関数によって返された参照を所有しているかどうかを誤って覚えておくこと、2)あなたがあなたよりも長い間参照を借りることが安全だと信じています。
周期的なゴミコレクターのために特別なことをする必要はありません。参照カウントで欠陥を修正するだけで、直接アクセスする必要はありません。
他のヒント
私がREFカウントで知っている最大のゴッチャとC APIは __del__
もの。何かへの借りた参照があるとき、あなたはその参照を使用している間にギルをあきらめないので、あなたはincref'ingなしで逃げることができると思います。ただし、オブジェクトを削除することになった場合(たとえば、リストから削除することにより)、トリガーをトリガーする可能性があります。 __del__
電話をかける可能性があります。とてもトリッキーです。
あなたがincref(そしてもちろん、もちろんdedref)を入手したすべての参照を入手するとすぐに、問題はないはずです。