#5298: clarify docs about GIL by using more consistent wording.

This commit is contained in:
Georg Brandl 2009-04-05 17:17:42 +00:00
parent 4af280ee98
commit 1ede0d670f
1 changed files with 79 additions and 78 deletions

View File

@ -394,12 +394,12 @@ Thread State and the Global Interpreter Lock
single: lock, interpreter single: lock, interpreter
The Python interpreter is not fully thread safe. In order to support The Python interpreter is not fully thread safe. In order to support
multi-threaded Python programs, there's a global lock that must be held by the multi-threaded Python programs, there's a global lock, called the :dfn:`global
current thread before it can safely access Python objects. Without the lock, interpreter lock` or :dfn:`GIL`, that must be held by the current thread before
even the simplest operations could cause problems in a multi-threaded program: it can safely access Python objects. Without the lock, even the simplest
for example, when two threads simultaneously increment the reference count of operations could cause problems in a multi-threaded program: for example, when
the same object, the reference count could end up being incremented only once two threads simultaneously increment the reference count of the same object, the
instead of twice. reference count could end up being incremented only once instead of twice.
.. index:: single: setcheckinterval() (in module sys) .. index:: single: setcheckinterval() (in module sys)
@ -428,9 +428,9 @@ This is easy enough in most cases. Most code manipulating the global
interpreter lock has the following simple structure:: interpreter lock has the following simple structure::
Save the thread state in a local variable. Save the thread state in a local variable.
Release the interpreter lock. Release the global interpreter lock.
...Do some blocking I/O operation... ...Do some blocking I/O operation...
Reacquire the interpreter lock. Reacquire the global interpreter lock.
Restore the thread state from the local variable. Restore the thread state from the local variable.
This is so common that a pair of macros exists to simplify it:: This is so common that a pair of macros exists to simplify it::
@ -447,7 +447,7 @@ The :cmacro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a
hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the
block. Another advantage of using these two macros is that when Python is block. Another advantage of using these two macros is that when Python is
compiled without thread support, they are defined empty, thus saving the thread compiled without thread support, they are defined empty, thus saving the thread
state and lock manipulations. state and GIL manipulations.
When thread support is enabled, the block above expands to the following code:: When thread support is enabled, the block above expands to the following code::
@ -479,7 +479,7 @@ There are some subtle differences; in particular, :cfunc:`PyEval_RestoreThread`
saves and restores the value of the global variable :cdata:`errno`, since the saves and restores the value of the global variable :cdata:`errno`, since the
lock manipulation does not guarantee that :cdata:`errno` is left alone. Also, lock manipulation does not guarantee that :cdata:`errno` is left alone. Also,
when thread support is disabled, :cfunc:`PyEval_SaveThread` and when thread support is disabled, :cfunc:`PyEval_SaveThread` and
:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case, :cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case,
:cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available. :cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available.
This is done so that dynamically loaded extensions compiled with thread support This is done so that dynamically loaded extensions compiled with thread support
enabled can be loaded by an interpreter that was compiled with disabled thread enabled can be loaded by an interpreter that was compiled with disabled thread
@ -562,16 +562,16 @@ supports the creation of additional interpreters (using
.. index:: module: thread .. index:: module: thread
When only the main thread exists, no lock operations are needed. This is a When only the main thread exists, no GIL operations are needed. This is a
common situation (most Python programs do not use threads), and the lock common situation (most Python programs do not use threads), and the lock
operations slow the interpreter down a bit. Therefore, the lock is not created operations slow the interpreter down a bit. Therefore, the lock is not
initially. This situation is equivalent to having acquired the lock: when created initially. This situation is equivalent to having acquired the lock:
there is only a single thread, all object accesses are safe. Therefore, when when there is only a single thread, all object accesses are safe. Therefore,
this function initializes the lock, it also acquires it. Before the Python when this function initializes the global interpreter lock, it also acquires
:mod:`thread` module creates a new thread, knowing that either it has the lock it. Before the Python :mod:`thread` module creates a new thread, knowing
or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When that either it has the lock or the lock hasn't been created yet, it calls
this call returns, it is guaranteed that the lock has been created and that the :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that
calling thread has acquired it. the lock has been created and that the calling thread has acquired it.
It is **not** safe to call this function when it is unknown which thread (if It is **not** safe to call this function when it is unknown which thread (if
any) currently has the global interpreter lock. any) currently has the global interpreter lock.
@ -582,7 +582,7 @@ supports the creation of additional interpreters (using
.. cfunction:: int PyEval_ThreadsInitialized() .. cfunction:: int PyEval_ThreadsInitialized()
Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This
function can be called without holding the lock, and therefore can be used to function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded. This function is avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time. not available when thread support is disabled at compile time.
@ -622,20 +622,20 @@ supports the creation of additional interpreters (using
.. cfunction:: PyThreadState* PyEval_SaveThread() .. cfunction:: PyThreadState* PyEval_SaveThread()
Release the interpreter lock (if it has been created and thread support is Release the global interpreter lock (if it has been created and thread
enabled) and reset the thread state to *NULL*, returning the previous thread support is enabled) and reset the thread state to *NULL*, returning the
state (which is not *NULL*). If the lock has been created, the current thread previous thread state (which is not *NULL*). If the lock has been created,
must have acquired it. (This function is available even when thread support is the current thread must have acquired it. (This function is available even
disabled at compile time.) when thread support is disabled at compile time.)
.. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate) .. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate)
Acquire the interpreter lock (if it has been created and thread support is Acquire the global interpreter lock (if it has been created and thread
enabled) and set the thread state to *tstate*, which must not be *NULL*. If the support is enabled) and set the thread state to *tstate*, which must not be
lock has been created, the current thread must not have acquired it, otherwise *NULL*. If the lock has been created, the current thread must not have
deadlock ensues. (This function is available even when thread support is acquired it, otherwise deadlock ensues. (This function is available even
disabled at compile time.) when thread support is disabled at compile time.)
.. cfunction:: void PyEval_ReInitThreads() .. cfunction:: void PyEval_ReInitThreads()
@ -679,60 +679,61 @@ example usage in the Python source distribution.
declaration. It is a no-op when thread support is disabled at compile time. declaration. It is a no-op when thread support is disabled at compile time.
All of the following functions are only available when thread support is enabled All of the following functions are only available when thread support is enabled
at compile time, and must be called only when the interpreter lock has been at compile time, and must be called only when the global interpreter lock has
created. been created.
.. cfunction:: PyInterpreterState* PyInterpreterState_New() .. cfunction:: PyInterpreterState* PyInterpreterState_New()
Create a new interpreter state object. The interpreter lock need not be held, Create a new interpreter state object. The global interpreter lock need not
but may be held if it is necessary to serialize calls to this function. be held, but may be held if it is necessary to serialize calls to this
function.
.. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp) .. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp)
Reset all information in an interpreter state object. The interpreter lock must Reset all information in an interpreter state object. The global interpreter
be held. lock must be held.
.. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp) .. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp)
Destroy an interpreter state object. The interpreter lock need not be held. Destroy an interpreter state object. The global interpreter lock need not be
The interpreter state must have been reset with a previous call to held. The interpreter state must have been reset with a previous call to
:cfunc:`PyInterpreterState_Clear`. :cfunc:`PyInterpreterState_Clear`.
.. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) .. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp)
Create a new thread state object belonging to the given interpreter object. The Create a new thread state object belonging to the given interpreter object.
interpreter lock need not be held, but may be held if it is necessary to The global interpreter lock need not be held, but may be held if it is
serialize calls to this function. necessary to serialize calls to this function.
.. cfunction:: void PyThreadState_Clear(PyThreadState *tstate) .. cfunction:: void PyThreadState_Clear(PyThreadState *tstate)
Reset all information in a thread state object. The interpreter lock must be Reset all information in a thread state object. The global interpreter lock
held. must be held.
.. cfunction:: void PyThreadState_Delete(PyThreadState *tstate) .. cfunction:: void PyThreadState_Delete(PyThreadState *tstate)
Destroy a thread state object. The interpreter lock need not be held. The Destroy a thread state object. The global interpreter lock need not be held.
thread state must have been reset with a previous call to The thread state must have been reset with a previous call to
:cfunc:`PyThreadState_Clear`. :cfunc:`PyThreadState_Clear`.
.. cfunction:: PyThreadState* PyThreadState_Get() .. cfunction:: PyThreadState* PyThreadState_Get()
Return the current thread state. The interpreter lock must be held. When the Return the current thread state. The global interpreter lock must be held.
current thread state is *NULL*, this issues a fatal error (so that the caller When the current thread state is *NULL*, this issues a fatal error (so that
needn't check for *NULL*). the caller needn't check for *NULL*).
.. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) .. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate)
Swap the current thread state with the thread state given by the argument Swap the current thread state with the thread state given by the argument
*tstate*, which may be *NULL*. The interpreter lock must be held. *tstate*, which may be *NULL*. The global interpreter lock must be held.
.. cfunction:: PyObject* PyThreadState_GetDict() .. cfunction:: PyObject* PyThreadState_GetDict()
@ -763,14 +764,15 @@ created.
.. cfunction:: PyGILState_STATE PyGILState_Ensure() .. cfunction:: PyGILState_STATE PyGILState_Ensure()
Ensure that the current thread is ready to call the Python C API regardless of Ensure that the current thread is ready to call the Python C API regardless
the current state of Python, or of its thread lock. This may be called as many of the current state of Python, or of the global interpreter lock. This may
times as desired by a thread as long as each call is matched with a call to be called as many times as desired by a thread as long as each call is
:cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used matched with a call to :cfunc:`PyGILState_Release`. In general, other
between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and
as the thread state is restored to its previous state before the Release(). For :cfunc:`PyGILState_Release` calls as long as the thread state is restored to
example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and its previous state before the Release(). For example, normal usage of the
:cmacro:`Py_END_ALLOW_THREADS` macros is acceptable. :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is
acceptable.
The return value is an opaque "handle" to the thread state when The return value is an opaque "handle" to the thread state when
:cfunc:`PyGILState_Ensure` was called, and must be passed to :cfunc:`PyGILState_Ensure` was called, and must be passed to
@ -808,35 +810,34 @@ pointer and a void argument.
.. index:: single: setcheckinterval() (in module sys) .. index:: single: setcheckinterval() (in module sys)
Every check interval, when the interpreter lock is released and reacquired, Every check interval, when the global interpreter lock is released and
python will also call any such provided functions. This can be used for reacquired, python will also call any such provided functions. This can be used
example by asynchronous IO handlers. The notification can be scheduled for example by asynchronous IO handlers. The notification can be scheduled from
from a worker thread and the actual call than made at the earliest a worker thread and the actual call than made at the earliest convenience by the
convenience by the main thread where it has possession of the global main thread where it has possession of the global interpreter lock and can
interpreter lock and can perform any Python API calls. perform any Python API calls.
.. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) ) .. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) )
.. index:: single: Py_AddPendingCall() .. index:: single: Py_AddPendingCall()
Post a notification to the Python main thread. If successful, Post a notification to the Python main thread. If successful, *func* will be
*func* will be called with the argument *arg* at the earliest called with the argument *arg* at the earliest convenience. *func* will be
convenience. *func* will be called having the global interpreter called having the global interpreter lock held and can thus use the full
lock held and can thus use the full Python API and can take any Python API and can take any action such as setting object attributes to
action such as setting object attributes to signal IO completion. signal IO completion. It must return 0 on success, or -1 signalling an
It must return 0 on success, or -1 signalling an exception. exception. The notification function won't be interrupted to perform another
The notification function won't be interrupted to perform another asynchronous notification recursively, but it can still be interrupted to
asynchronous notification recursively, switch threads if the global interpreter lock is released, for example, if it
but it can still be interrupted to switch threads if the interpreter calls back into python code.
lock is released, for example, if it calls back into python code.
This function returns 0 on success in which case the notification has been This function returns 0 on success in which case the notification has been
scheduled. Otherwise, for example if the notification buffer is full, scheduled. Otherwise, for example if the notification buffer is full, it
it returns -1 without setting any exception. returns -1 without setting any exception.
This function can be called on any thread, be it a Python thread or This function can be called on any thread, be it a Python thread or some
some other system thread. If it is a Python thread, it doesn't matter if other system thread. If it is a Python thread, it doesn't matter if it holds
it holds the global interpreter lock or not. the global interpreter lock or not.
.. versionadded:: 2.7 .. versionadded:: 2.7