Domanda

Proprio per il puro gusto di farlo, ho deciso di creare un schema vincolante per libpython così è possibile incorporare Python in programmi Scheme. Sono già in grado di mettere in C API di Python, ma non ho davvero pensato di gestione della memoria.

FFI del MzScheme modo in cui funziona è che posso chiamare una funzione, e se quella funzione restituisce un puntatore ad un PyObject, allora posso farlo incrementare automaticamente il conteggio dei riferimenti. Poi, posso registrare un finalizzatore che diminuire il conteggio dei riferimenti quando l'oggetto Schema diventa garbage collection. Ho guardato il documentazione per il conteggio dei riferimenti , e non vedere alcun problema con questo a prima vista (anche se può essere sub-ottimale in alcuni casi). Ci sono dei trucchi mi manca?

Inoltre, sto avendo difficoltà a fare testa o croce del ciclico documentazione garbage collector . Quali sono le cose dovrò tenere a mente qui? In particolare, come faccio a fare Python consapevole che ho un riferimento a qualcosa di così non raccoglie mentre sto ancora usando?

È stato utile?

Soluzione

Il tuo link per http://docs.python.org/extending/extending .html # riferimento-conti è il posto giusto. Il radicamento e Python / C sezioni API estendere e della documentazione sono quelli che vi spiegherà come utilizzare l'API C.

conteggio di riferimento è una delle parti fastidiose utilizzando l'API C. Il Gotcha principale è mantenere tutto dritto: a seconda della funzione API si chiama, si può o non possiede il riferimento all'oggetto che si ottiene. Fare attenzione per capire se si è posseduta (e quindi non può dimenticare di DECREF o darlo a qualcosa che rubare) o stanno prendendo in prestito (e deve INCREF per tenerlo e possibilmente da utilizzare durante la funzione). La maggior parte dei bug comuni che coinvolgono questo sono 1) ricordando in modo non corretto se si possiede un riferimento restituito da una particolare funzione e 2) si credendo di essere al sicuro per prendere in prestito un riferimento per un tempo più lungo di quello che sono.

Non devi fare nulla di speciale per il garbage collector ciclico. E 'solo lì per rattoppare un difetto nel conteggio di riferimento e non richiede l'accesso diretto.

Altri suggerimenti

Il più grande Gotcha so che con il conteggio ref e l'API C è la cosa __del__. Quando si dispone di un riferimento preso in prestito per qualcosa, è che si può ottenere via senza INCREF'ing perché non dare la GIL mentre si utilizza tale riferimento. Ma, se si finisce per l'eliminazione di un oggetto (da, per esempio, la rimozione da un elenco), è possibile che si attiva una chiamata __del__, che potrebbe rimuovere il riferimento che stai prendendo in prestito da sotto i piedi. Molto difficile.

Se INCREF (e poi DECREF, naturalmente) tutti i riferimenti presi a prestito, non appena li si ottiene, non ci dovrebbe essere alcun problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top