Есть ли какой-либо подсчет ссылок Python / глюки сборки "мусора" при контакте с кодом C?

Только для чистого heck его, я решил создать привязку Схемы к libpython, таким образом, можно встроить Python в программах Схемы. Я уже могу звонить в API Python C, но я действительно не думал об управлении памятью.

Путем FFI mzscheme работает, то, что я могу вызвать функцию, и если та функция возвращает указатель на a PyObject, затем у меня может быть он, автоматически увеличивают подсчет ссылок. Затем я могу зарегистрировать финализатор, который постепенно уменьшит подсчет ссылок, когда объект Схемы будет собран "мусор". Я посмотрел на документацию для подсчета ссылок и не вижу проблем с этим на первый взгляд (хотя это может быть субоптимальным в некоторых случаях). Есть ли какие-либо глюки, которые я пропускаю?

Кроме того, я испытываю затруднения, понимающие циклическую документацию сборщика "мусора". Какие вещи я должен буду принять во внимание здесь? В частности, как я делаю Python знающим, что у меня есть ссылка на что-то так, что он не собирает его, в то время как я все еще использую его?

6
задан Jason Baker 29 May 2010 в 13:13
поделиться

2 ответа

Ваша ссылка на http://docs.python.org/extending/extending.html#reference-counts - правильное место. Разделы документации "Расширение и встраивание" и "Python/C API" объясняют, как использовать C API.

Подсчет ссылок - одна из самых неприятных частей использования C API. Основная проблема заключается в том, чтобы держать все в порядке: В зависимости от функции API, которую вы вызываете, вы можете владеть или не владеть ссылкой на объект, который вы получаете. Будьте внимательны, чтобы понять, владеете ли вы им (и, следовательно, не можете забыть уменьшить его или передать его чему-то, что украдет его) или заимствуете его (и должны увеличить его, чтобы сохранить его и, возможно, использовать его в вашей функции). Наиболее распространенными ошибками, связанными с этим, являются 1) неправильное запоминание того, принадлежит ли вам ссылка, возвращаемая определенной функцией, и 2) уверенность в том, что вы можете заимствовать ссылку на более длительное время, чем это есть на самом деле.

Вам не нужно делать ничего особенного для циклического сборщика мусора. Он нужен только для устранения недостатка в подсчете ссылок и не требует прямого доступа.

7
ответ дан 10 December 2019 в 00:34
поделиться

Самая большая проблема, связанная с подсчетом ссылок и C API, - это __ del __ . Когда у вас есть заимствованная ссылка на что-то, вы думаете, что можете обойтись без INCREF, потому что вы не отказываетесь от GIL, пока используете эту ссылку. Но если вы в конечном итоге удаляете объект (например, удаляя его из списка), возможно, вы запускаете вызов __ del __ , который может удалить ссылку, которую вы заимствуете из-под ваших ног. . Очень сложно.

Если вы INCREF (а затем, конечно, DECREF) все заимствованные ссылки, как только вы их получите, не должно возникнуть никаких проблем.

3
ответ дан 10 December 2019 в 00:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: