[Python-Dev] Making python C-API thread safe (try 2)

Harri Pesonen fuerte at sci.fi
Thu Sep 11 20:53:10 EDT 2003


Sorry about the previous post! :-)

Background: I'm new to Python. I just embedded Python into a 
multi-threaded application, and extended Python by callbacks as well. 
During this process I realised that Python is not internally as 
beautiful as externally. It is not thread safe. This surprised me, 
because Python is a quite young programming language. I started thinking 
how to fix this, how to make Python thread safe. Currently Python does 
not support multiprocessor machines or hyperthreading processors. It is 
only a matter of time when this has to be fixed, better soon than later.

How to make C-API thread safe: It's quite simple, in fact. Thread should 
first call

PyThreadState* Py_NewInterpreter()

and use this thread state pointer in every following API call. This 
thread state pointer should point to a memory structure, that holds 
everything that Python interpreter needs. There should be no global 
variables, not even None, except

const char* Py_GetVersion()

and such. So every Python function should have this thread state as the 
first argument:

int PyRun_SimpleString(PyThreadState*tstate, char *command)

and so on. Also callbacks should have it, about every API function.

Advantages: The following functions would not be needed any more, it 
would make the API much simpler:

void PyEval_InitThreads( )
void PyEval_AcquireLock( )
void PyEval_ReleaseLock( )
void PyEval_AcquireThread( PyThreadState *tstate)
void PyEval_ReleaseThread( PyThreadState *tstate)
PyThreadState* PyEval_SaveThread( )
void PyEval_RestoreThread( PyThreadState *tstate)
Py_BEGIN_ALLOW_THREADS
Py_END_ALLOW_THREADS
Py_BLOCK_THREADS
Py_UNBLOCK_THREADS
PyInterpreterState* PyInterpreterState_New( )
void PyInterpreterState_Clear( PyInterpreterState *interp)
void PyInterpreterState_Delete( PyInterpreterState *interp)
PyThreadState* PyThreadState_New( PyInterpreterState *interp)
void PyThreadState_Clear( PyThreadState *tstate)
void PyThreadState_Delete( PyThreadState *tstate)
PyThreadState* PyThreadState_Get( )
PyThreadState* PyThreadState_Swap( PyThreadState *tstate)

The current documentation says: "In order to support multi-threaded 
Python programs, the interpreter regularly releases and reacquires the 
lock -- by default, every 100 bytecode instructions". This would not be 
needed anymore. It would make the interpreter faster.

Making this change would take a couple of weeks, if the job would be 
divided between modules to different persons. The change is trivial, but 
it would have to be made everywhere.

Disadvantages: Everything old would break. Thread safe Python should 
have a version number significantly higher, like Python 3. Old 
applications would work with old Python versions, with old Python DLLs, 
but they would need to be rewritten for the new API. It would be a 
trivial task, but still.

Disclaimer: I already got mail saying: "

This issue gets discussed regularly on comp.lang.python; python-dev is
for discussion of specific changes to the Python language and libraries.
Until you are familiar with the way threading works in Python and have
some concrete proposal to make, please keep the discussion on c.l.py."

The current situation is very unfortunate, having a single threaded implementation in the modern computer age. I have a concrete proposal, which would break everything :-) but I think that is the only solution.

Thanks for reading,

Harri






More information about the Python-Dev mailing list