How to free /destroy object created by PyTuple_New

G

grbgooglefan

I am using PyTuple_New to pass function arguments to
PyObject_CallObject for execution of a Python function.

How can I free up the memory and object allocated by the PyTuple_New
function?

I am using Python interpreter in my multi-threaded C application & at
load condition my application crashes in Python's evaluation function.
I am not explicitely releasing the PyTuple_New object.

Please guide how can I destory object created by PyTuple_New?
 
A

Andrew Svetlov

To destroy every python object you need to call Py_DECREF.
To call python code fron you C thread you need to use pair
PyGILState_Ensure/PyGILState_Release.
 
G

grbgooglefan

To destroy every python object you need to call Py_DECREF.
To call python code fron you C thread you need to use pair
PyGILState_Ensure/PyGILState_Release.

In my case, my C application has multiple threads & they are accessing
a single Python Interpreter which was initialized by 1st main thread.
In that case also, do I need to use PyGILState_Ensure/
PyGILState_Release APIs?

I am not using Python interpreter level threads.

Can I have a Python interpreter per thread so that I won't have issues
of some data inside Python interpreters being gettint accidently
overwritten/ freed by other thread?

Will Py_DECREF release the items set in that tuple using call to
PyTuple_SetItem? Or do I need to separately call Py_DECREF for them
also?
What is correct sequence for calling Py_DECREF & Py_INCREF?
If I dont call Py_DECREF, will that object (PyTuple) not get freeed at
all, causing memory leak?

Please guide.
 
H

Hrvoje Niksic

[ You can also ask questions like this on the specialized capi-sig
list; see http://mail.python.org/mailman/listinfo/capi-sig ]

grbgooglefan said:
In my case, my C application has multiple threads & they are accessing
a single Python Interpreter which was initialized by 1st main thread.
In that case also, do I need to use PyGILState_Ensure/
PyGILState_Release APIs?

Yes. There is a single GIL that needs to be held even if each thread
has a different interpreter.
Can I have a Python interpreter per thread so that I won't have
issues of some data inside Python interpreters being gettint
accidently overwritten/ freed by other thread?

You can have a separate interpreter per thread, but they will still
need to be synchronized using the GIL because even separate
interpreters share some global data, such as C-level global variables.
Will Py_DECREF release the items set in that tuple using call to
PyTuple_SetItem? Or do I need to separately call Py_DECREF for them
also?

A single Py_DECREF on the tuple will call Py_DECREF on all the
contained objects. This principle applies to all containers.
What is correct sequence for calling Py_DECREF & Py_INCREF?

If you receive a "new" reference, you don't need to initially incref
it. You need to call DECREF when you're done with the object,
i.e. when it stops being accessible for you (for example because you
replaced it with another object or NULL in your C-level data
structure).
If I dont call Py_DECREF, will that object (PyTuple) not get freeed
at all, causing memory leak?

Yes, and additionally it causes objects inside it to leak as well.
 
G

grbgooglefan

Regarding PyTuple_New, when I pass this tuple with variable values set
to some evaluation function like PyObject_CallObject, do I need to
increment reference for this tuple & then decrement again after the
call returns?

If I've not configured my libpython with threads when compiling, will
PyGILState_Release, etc. calls still work?
For PyGILState_Release/Acquire calls do I need to create the lock
explicitely or it will get created internally by Interpreter when
Interpreter is initialized?
Please guide.
 
H

Hrvoje Niksic

grbgooglefan said:
Regarding PyTuple_New, when I pass this tuple with variable values
set to some evaluation function like PyObject_CallObject, do I need
to increment reference for this tuple & then decrement again after
the call returns?

You don't. It is assumed that you already own the reference to the
tuple, so you can freely pass it to functions. When you're done with
the tuple (such as when you're about to leave the C scope that holds
the reference to it), you're suppose to decref it. If the function
you call stores it somewhere, that function is responsible for
incrementing its reference count.

The exception to the above are functions documented to "steal" the
reference count of their arguments, such as PyList_SetItem, but those
are generally quite rare and always clearly documented.

Maybe you should post a question to the capi-sig list explaining what
you're trying to do; perhaps there's a better way to do it. For
example, maybe you don't need to create a tuple and then call
PyObject_CallObject, but simply use PyObject_CallFunction, which will
create the tuple for you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,294
Messages
2,571,508
Members
48,193
Latest member
DannyRober

Latest Threads

Top