6

방금 ​​그랬듯이 나는 Scheme binding to libpython을 만들기로 결정했습니다. 그래서 당신은 Scheme 프로그램에 파이썬을 내장 할 수 있습니다. 이미 Python의 C API를 호출 할 수 있지만 메모리 관리는 실제로 생각하지 않았습니다.C 코드를 다룰 때 Python 참조 카운팅/가비지 콜렉션이 있습니까?

mzscheme의 FFI가 작동하는 방식은 함수를 호출 할 수 있으며 함수가 PyObject에 대한 포인터를 반환하면 참조 횟수를 자동으로 증가시킬 수 있습니다. 그런 다음 Scheme 객체가 가비지 수집 될 때 참조 카운트를 감소시키는 finalizer를 등록 할 수 있습니다. 나는 documentation for reference counting을보고 (일부 경우에는 차선책 일 수도 있지만) 언뜻보기에는 아무런 문제가 보이지 않습니다. 내가 누락 된 문제가 있습니까?

또한, cyclic garbage collector documentation의 머리 또는 꼬리를 만드는 데 문제가 있습니다. 내가 여기서 염두에 두어야 할 것은 무엇인가? 특히, 파이썬이 내가 무언가에 대한 참조를 가지고 있다는 것을 어떻게 인식 시켜서 내가 그것을 사용하는 동안 그것을 모으지 않는가?

답변

7

http://docs.python.org/extending/extending.html#reference-counts에 대한 링크가 적합합니다. 문서의 Extending and Embedding과 Python/C API 섹션은 C API 사용법을 설명합니다.

참조 계산은 C API 사용의 성가신 부분 중 하나입니다. 주요한 문제는 모든 것을 똑바로 유지합니다. 호출하는 API 함수에 따라 가져 오는 객체에 대한 참조를 소유하고 있거나 소유하지 않을 수도 있습니다. 당신이 그것을 소유하고 있는지 (그리고 따라서 그것을 깎아 내리거나 그것을 훔쳐 갈 무언가에 포기하는 것을 잊지 마라) 그것을 빌리는 것 (그리고 그것을 유지하고 그것을 당신의 기능 중에도 사용할 수 있음을 깨달아야한다)을 이해하는 것을 조심하십시오. 이와 관련된 가장 일반적인 버그는 1) 특정 함수에 의해 반환 된 참조를 소유하고 있는지 여부를 잘못 기억하고 있고 2) 자신보다 긴 시간 동안 참조를 빌려도 안전하다고 믿는 경우입니다.

순환 가비지 수집기에 특별한 작업을 수행 할 필요가 없습니다. 참조 카운트의 결함을 패치하기위한 것일 뿐이며 직접 액세스 할 필요가 없습니다.

+0

그래서 ... 파이썬은 순환 계산을 위해 참조 카운팅 *과 * 가비지 컬렉터를 사용합니까? 그것은 꽤 심각한 결함입니다. 디자인 종류. 파이썬 측 사이클에 참여하는 값이 스키마에 노출되어 있으면 Jason에서 훨씬 재미있는 일이 될 것입니다. –

+0

좋은 정보. 내가 그것을 얻었을 때 모든 것을 INCREF하고, 내가 그것을 마쳤을 때 모든 것을 DECREF한다면, 나는 괜찮은가? 아니면 제가 갈 수있는 문제가 있습니까? –

+2

@ Jason, INCREF * 빌려온 * 참조 만. 일부 함수는 이미 INCREF로 처리 된 * new * 참조를 반환합니다. 그것을 INCREF하면 메모리 누출이 발생합니다. –

3

ref 카운팅 및 C API에서 가장 큰 문제는 __del__입니다. 빌린 참조가있을 때, 당신은 그 참조를 사용하는 동안 GIL을 포기하지 않기 때문에 INCREF'ing하지 않고 도망 갈 수 있다고 생각합니다. 그러나 객체를 삭제 (예 : 목록에서 제거)하면 __del__ 호출이 트리거 될 수 있습니다. 이로 인해 차용 중 참조를 제거 할 수 있습니다. 아주 까다 롭습니다.

빌린 참조 문헌을 가져 오는 즉시 INCREF (그리고 DECREF, 물론 DECREF)하면 아무런 문제가 없어야합니다.