Thread states and the global interpreter lock

Unless on afree-threaded build ofCPython,the Python interpreter is generally not thread-safe. In order to supportmulti-threaded Python programs, there’s a global lock, called theglobalinterpreter lock orGIL, that must be held by a thread beforeaccessing Python objects. Without the lock, even the simplest operationscould cause problems in a multi-threaded program: for example, whentwo threads simultaneously increment the reference count of the same object, thereference count could end up being incremented only once instead of twice.

As such, only a thread that holds the GIL may operate on Python objects orinvoke Python’s C API.

In order to emulate concurrency, the interpreter regularly tries to switchthreads between bytecode instructions (seesys.setswitchinterval()).This is why locks are also necessary for thread-safety in pure-Python code.

Additionally, the global interpreter lock is released around blocking I/Ooperations, such as reading or writing to a file. From the C API, this is donebydetaching the thread state.

The Python interpreter keeps some thread-local information insidea data structure calledPyThreadState, known as athread state.Each thread has a thread-local pointer to aPyThreadState; a thread statereferenced by this pointer is considered to beattached.

A thread can only have oneattached thread state at a time. An attachedthread state is typically analogous with holding the GIL, except onfree-threaded builds. On builds with the GIL enabled, attaching a thread statewill block until the GIL can be acquired. However, even on builds with the GILdisabled, it is still required to have an attached thread state, as the interpreterneeds to keep track of which threads may access Python objects.

Note

Even on the free-threaded build, attaching a thread state may block, as theGIL can be re-enabled or threads might be temporarily suspended (such as duringa garbage collection).

Generally, there will always be an attached thread state when using Python’sC API, including during embedding and when implementing methods, so it’s uncommonto need to set up a thread state on your own. Only in some specific cases, suchas in aPy_BEGIN_ALLOW_THREADS block or in a fresh thread, will thethread not have an attached thread state.If uncertain, check ifPyThreadState_GetUnchecked() returnsNULL.

If it turns out that you do need to create a thread state, callPyThreadState_New()followed byPyThreadState_Swap(), or use the dangerousPyGILState_Ensure() function.

Detaching the thread state from extension code

Most extension code manipulating thethread state has the following simplestructure:

Savethethreadstateinalocalvariable....DosomeblockingI/Ooperation...Restorethethreadstatefromthelocalvariable.

This is so common that a pair of macros exists to simplify it:

Py_BEGIN_ALLOW_THREADS...DosomeblockingI/Ooperation...Py_END_ALLOW_THREADS

ThePy_BEGIN_ALLOW_THREADS macro opens a new block and declares ahidden local variable; thePy_END_ALLOW_THREADS macro closes theblock.

The block above expands to the following code:

PyThreadState*_save;_save=PyEval_SaveThread();...DosomeblockingI/Ooperation...PyEval_RestoreThread(_save);

Here is how these functions work:

The attached thread state implies that the GIL is held for the interpreter.To detach it,PyEval_SaveThread() is called and the result is storedin a local variable.

By detaching the thread state, the GIL is released, which allows other threadsto attach to the interpreter and execute while the current thread performsblocking I/O. When the I/O operation is complete, the old thread state isreattached by callingPyEval_RestoreThread(), which will wait untilthe GIL can be acquired.

Note

Performing blocking I/O is the most common use case for detachingthe thread state, but it is also useful to call it over long-runningnative code that doesn’t need access to Python objects or Python’s C API.For example, the standardzlib andhashlib modules detach thethread state when compressing or hashingdata.

On afree-threaded build, theGIL is usually out of the question,butdetaching the thread state is still required, because the interpreterperiodically needs to block all threads to get a consistent view of Python objectswithout the risk of race conditions.For example, CPython currently suspends all threads for a short period of timewhile running the garbage collector.

Warning

Detaching the thread state can lead to unexpected behavior during interpreterfinalization. SeeCautions regarding runtime finalization for moredetails.

APIs

The following macros are normally used without a trailing semicolon; look forexample usage in the Python source distribution.

Note

These macros are still necessary on thefree-threaded build to preventdeadlocks.

Py_BEGIN_ALLOW_THREADS
Part of theStable ABI.

This macro expands to{PyThreadState*_save;_save=PyEval_SaveThread();.Note that it contains an opening brace; it must be matched with a followingPy_END_ALLOW_THREADS macro. See above for further discussion of thismacro.

Py_END_ALLOW_THREADS
Part of theStable ABI.

This macro expands toPyEval_RestoreThread(_save);}. Note that it containsa closing brace; it must be matched with an earlierPy_BEGIN_ALLOW_THREADS macro. See above for further discussion ofthis macro.

Py_BLOCK_THREADS
Part of theStable ABI.

This macro expands toPyEval_RestoreThread(_save);: it is equivalent toPy_END_ALLOW_THREADS without the closing brace.

Py_UNBLOCK_THREADS
Part of theStable ABI.

This macro expands to_save=PyEval_SaveThread();: it is equivalent toPy_BEGIN_ALLOW_THREADS without the opening brace and variabledeclaration.

Non-Python created threads

When threads are created using the dedicated Python APIs (such as thethreading module), a thread state is automatically associated with them,However, when a thread is created from native code (for example, by athird-party library with its own thread management), it doesn’t hold anattached thread state.

If you need to call Python code from these threads (often this will be partof a callback API provided by the aforementioned third-party library),you must first register these threads with the interpreter bycreating a new thread state and attaching it.

The most robust way to do this is throughPyThreadState_New() followedbyPyThreadState_Swap().

Note

PyThreadState_New requires an argument pointing to the desiredinterpreter; such a pointer can be acquired via a call toPyInterpreterState_Get() from the code where the thread wascreated.

For example:

/* The return value of PyInterpreterState_Get() from the   function that created this thread. */PyInterpreterState*interp=thread_data->interp;/* Create a new thread state for the interpreter. It does not start out   attached. */PyThreadState*tstate=PyThreadState_New(interp);/* Attach the thread state, which will acquire the GIL. */PyThreadState_Swap(tstate);/* Perform Python actions here. */result=CallSomeFunction();/* evaluate result or handle exception *//* Destroy the thread state. No Python API allowed beyond this point. */PyThreadState_Clear(tstate);PyThreadState_DeleteCurrent();

Warning

If the interpreter finalized beforePyThreadState_Swap was called, theninterp will be a dangling pointer!

Legacy API

Another common pattern to call Python code from a non-Python thread is to usePyGILState_Ensure() followed by a call toPyGILState_Release().

These functions do not work well when multiple interpreters exist in the Pythonprocess. If no Python interpreter has ever been used in the current thread (whichis common for threads created outside Python),PyGILState_Ensure will createand attach a thread state for the “main” interpreter (the first interpreter inthe Python process).

Additionally, these functions have thread-safety issues during interpreterfinalization. UsingPyGILState_Ensure during finalization will likelycrash the process.

Usage of these functions look like such:

PyGILState_STATEgstate;gstate=PyGILState_Ensure();/* Perform Python actions here. */result=CallSomeFunction();/* evaluate result or handle exception *//* Release the thread. No Python API allowed beyond this point. */PyGILState_Release(gstate);

Cautions about fork()

Another important thing to note about threads is their behaviour in the faceof the Cfork() call. On most systems withfork(), after aprocess forks only the thread that issued the fork will exist. This has aconcrete impact both on how locks must be handled and on all stored statein CPython’s runtime.

The fact that only the “current” thread remainsmeans any locks held by other threads will never be released. Python solvesthis foros.fork() by acquiring the locks it uses internally beforethe fork, and releasing them afterwards. In addition, it resets anyLock objects in the child. When extending or embedding Python, thereis no way to inform Python of additional (non-Python) locks that need to beacquired before or reset after a fork. OS facilities such aspthread_atfork() would need to be used to accomplish the same thing.Additionally, when extending or embedding Python, callingfork()directly rather than throughos.fork() (and returning to or callinginto Python) may result in a deadlock by one of Python’s internal locksbeing held by a thread that is defunct after the fork.PyOS_AfterFork_Child() tries to reset the necessary locks, but is notalways able to.

The fact that all other threads go away also means that CPython’sruntime state there must be cleaned up properly, whichos.fork()does. This means finalizing all otherPyThreadState objectsbelonging to the current interpreter and all otherPyInterpreterState objects. Due to this and the specialnature of the“main” interpreter,fork() should only be called in that interpreter’s “main”thread, where the CPython global runtime was originally initialized.The only exception is ifexec() will be called immediatelyafter.

High-level APIs

These are the most commonly used types and functions when writing multi-threadedC extensions.

typePyThreadState
Part of theLimited API (as an opaque struct).

This data structure represents the state of a single thread. The only publicdata member is:

PyInterpreterState*interp

This thread’s interpreter state.

voidPyEval_InitThreads()
Part of theStable ABI.

Deprecated function which does nothing.

In Python 3.6 and older, this function created the GIL if it didn’t exist.

Changed in version 3.9:The function now does nothing.

Changed in version 3.7:This function is now called byPy_Initialize(), so you don’thave to call it yourself anymore.

Changed in version 3.2:This function cannot be called beforePy_Initialize() anymore.

Deprecated since version 3.9.

PyThreadState*PyEval_SaveThread()
Part of theStable ABI.

Detach theattached thread state and return it.The thread will have nothread state upon returning.

voidPyEval_RestoreThread(PyThreadState*tstate)
Part of theStable ABI.

Set theattached thread state totstate.The passedthread stateshould not beattached,otherwise deadlock ensues.tstate will be attached upon returning.

Note

Calling this function from a thread when the runtime is finalizing willhang the thread until the program exits, even if the thread was notcreated by Python. Refer toCautions regarding runtime finalization for more details.

Changed in version 3.14:Hangs the current thread, rather than terminating it, if called while theinterpreter is finalizing.

PyThreadState*PyThreadState_Get()
Part of theStable ABI.

Return theattached thread state. If the thread has no attachedthread state, (such as when inside ofPy_BEGIN_ALLOW_THREADSblock), then this issues a fatal error (so that the caller needn’t checkforNULL).

See alsoPyThreadState_GetUnchecked().

PyThreadState*PyThreadState_GetUnchecked()

Similar toPyThreadState_Get(), but don’t kill the process with afatal error if it is NULL. The caller is responsible to check if the resultis NULL.

Added in version 3.13:In Python 3.5 to 3.12, the function was private and known as_PyThreadState_UncheckedGet().

PyThreadState*PyThreadState_Swap(PyThreadState*tstate)
Part of theStable ABI.

Set theattached thread state totstate, and return thethread state that was attached prior to calling.

This function is safe to call without anattached thread state; itwill simply returnNULL indicating that there was no prior thread state.

Note

Similar toPyGILState_Ensure(), this function will hang thethread if the runtime is finalizing.

GIL-state APIs

The following functions use thread-local storage, and are not compatiblewith sub-interpreters:

typePyGILState_STATE
Part of theStable ABI.

The type of the value returned byPyGILState_Ensure() and passed toPyGILState_Release().

enumeratorPyGILState_LOCKED

The GIL was already held whenPyGILState_Ensure() was called.

enumeratorPyGILState_UNLOCKED

The GIL was not held whenPyGILState_Ensure() was called.

PyGILState_STATEPyGILState_Ensure()
Part of theStable ABI.

Ensure that the current thread is ready to call the Python C API regardlessof the current state of Python, or of theattached thread state. This maybe called as many times as desired by a thread as long as each call ismatched with a call toPyGILState_Release(). In general, otherthread-related APIs may be used betweenPyGILState_Ensure() andPyGILState_Release() calls as long as the thread state is restored toits previous state before the Release(). For example, normal usage of thePy_BEGIN_ALLOW_THREADS andPy_END_ALLOW_THREADS macros isacceptable.

The return value is an opaque “handle” to theattached thread state whenPyGILState_Ensure() was called, and must be passed toPyGILState_Release() to ensure Python is left in the same state. Eventhough recursive calls are allowed, these handlescannot be shared - eachunique call toPyGILState_Ensure() must save the handle for its calltoPyGILState_Release().

When the function returns, there will be anattached thread stateand the thread will be able to call arbitrary Python code. Failure is a fatal error.

Warning

Calling this function when the runtime is finalizing is unsafe. Doingso will either hang the thread until the program ends, or fully crashthe interpreter in rare cases. Refer toCautions regarding runtime finalization for more details.

Changed in version 3.14:Hangs the current thread, rather than terminating it, if called while theinterpreter is finalizing.

voidPyGILState_Release(PyGILState_STATE)
Part of theStable ABI.

Release any resources previously acquired. After this call, Python’s state willbe the same as it was prior to the correspondingPyGILState_Ensure() call(but generally this state will be unknown to the caller, hence the use of theGILState API).

Every call toPyGILState_Ensure() must be matched by a call toPyGILState_Release() on the same thread.

PyThreadState*PyGILState_GetThisThreadState()
Part of theStable ABI.

Get theattached thread state for this thread. May returnNULL if noGILState API has been used on the current thread. Note that the main threadalways has such a thread-state, even if no auto-thread-state call has beenmade on the main thread. This is mainly a helper/diagnostic function.

Note

This function may return non-NULL even when thethread stateis detached.PreferPyThreadState_Get() orPyThreadState_GetUnchecked()for most cases.

intPyGILState_Check()

Return1 if the current thread is holding theGIL and0 otherwise.This function can be called from any thread at any time.Only if it has had itsthread state initializedviaPyGILState_Ensure() will it return1.This is mainly a helper/diagnostic function. It can be usefulfor example in callback contexts or memory allocation functions whenknowing that theGIL is locked can allow the caller to perform sensitiveactions or otherwise behave differently.

Note

If the current Python process has ever created a subinterpreter, thisfunction willalways return1. PreferPyThreadState_GetUnchecked()for most cases.

Added in version 3.4.

Low-level APIs

PyThreadState*PyThreadState_New(PyInterpreterState*interp)
Part of theStable ABI.

Create a new thread state object belonging to the given interpreter object.Anattached thread state is not needed.

voidPyThreadState_Clear(PyThreadState*tstate)
Part of theStable ABI.

Reset all information in athread state object.tstatemust beattached

Changed in version 3.9:This function now calls thePyThreadState.on_delete callback.Previously, that happened inPyThreadState_Delete().

Changed in version 3.13:ThePyThreadState.on_delete callback was removed.

voidPyThreadState_Delete(PyThreadState*tstate)
Part of theStable ABI.

Destroy athread state object.tstate should notbeattached to any thread.tstate must have been reset with a previous call toPyThreadState_Clear().

voidPyThreadState_DeleteCurrent(void)

Detach theattached thread state (which must have been resetwith a previous call toPyThreadState_Clear()) and then destroy it.

Nothread state will beattached uponreturning.

PyFrameObject*PyThreadState_GetFrame(PyThreadState*tstate)
Part of theStable ABI since version 3.10.

Get the current frame of the Python thread statetstate.

Return astrong reference. ReturnNULL if no frame is currentlyexecuting.

See alsoPyEval_GetFrame().

tstate must not beNULL, and must beattached.

Added in version 3.9.

uint64_tPyThreadState_GetID(PyThreadState*tstate)
Part of theStable ABI since version 3.10.

Get the uniquethread state identifier of the Python thread statetstate.

tstate must not beNULL, and must beattached.

Added in version 3.9.

PyInterpreterState*PyThreadState_GetInterpreter(PyThreadState*tstate)
Part of theStable ABI since version 3.10.

Get the interpreter of the Python thread statetstate.

tstate must not beNULL, and must beattached.

Added in version 3.9.

voidPyThreadState_EnterTracing(PyThreadState*tstate)

Suspend tracing and profiling in the Python thread statetstate.

Resume them using thePyThreadState_LeaveTracing() function.

Added in version 3.11.

voidPyThreadState_LeaveTracing(PyThreadState*tstate)

Resume tracing and profiling in the Python thread statetstate suspendedby thePyThreadState_EnterTracing() function.

See alsoPyEval_SetTrace() andPyEval_SetProfile()functions.

Added in version 3.11.

intPyUnstable_ThreadState_SetStackProtection(PyThreadState*tstate,void*stack_start_addr,size_tstack_size)
This isUnstable API. It may change without warning in minor releases.

Set the stack protection start address and stack protection sizeof a Python thread state.

On success, return0.On failure, set an exception and return-1.

CPython implementsrecursion control for C code by raisingRecursionError when it notices that the machine execution stack is closeto overflow. See for example thePy_EnterRecursiveCall() function.For this, it needs to know the location of the current thread’s stack, which itnormally gets from the operating system.When the stack is changed, for example using context switching techniques like theBoost library’sboost::context, you must callPyUnstable_ThreadState_SetStackProtection() to inform CPython of the change.

CallPyUnstable_ThreadState_SetStackProtection() either beforeor after changing the stack.Do not call any other Python C API between the call and the stackchange.

SeePyUnstable_ThreadState_ResetStackProtection() for undoing this operation.

Added in version 3.15.

voidPyUnstable_ThreadState_ResetStackProtection(PyThreadState*tstate)
This isUnstable API. It may change without warning in minor releases.

Reset the stack protection start address and stack protection sizeof a Python thread state to the operating system defaults.

SeePyUnstable_ThreadState_SetStackProtection() for an explanation.

Added in version 3.15.

PyObject*PyThreadState_GetDict()
Return value: Borrowed reference. Part of theStable ABI.

Return a dictionary in which extensions can store thread-specific stateinformation. Each extension should use a unique key to use to store state inthe dictionary. It is okay to call this function when nothread stateisattached. If this function returnsNULL, no exception has been raised and the caller should assume nothread state is attached.

voidPyEval_AcquireThread(PyThreadState*tstate)
Part of theStable ABI.

Attachtstate to the current thread,which must not beNULL or alreadyattached.

The calling thread must not already have anattached thread state.

Note

Calling this function from a thread when the runtime is finalizing willhang the thread until the program exits, even if the thread was notcreated by Python. Refer toCautions regarding runtime finalization for more details.

Changed in version 3.8:Updated to be consistent withPyEval_RestoreThread(),Py_END_ALLOW_THREADS(), andPyGILState_Ensure(),and terminate the current thread if called while the interpreter is finalizing.

Changed in version 3.14:Hangs the current thread, rather than terminating it, if called while theinterpreter is finalizing.

PyEval_RestoreThread() is a higher-level function which is alwaysavailable (even when threads have not been initialized).

voidPyEval_ReleaseThread(PyThreadState*tstate)
Part of theStable ABI.

Detach theattached thread state.Thetstate argument, which must not beNULL, is only used to checkthat it represents theattached thread state — if it isn’t, a fatal error isreported.

PyEval_SaveThread() is a higher-level function which is alwaysavailable (even when threads have not been initialized).

Asynchronous notifications

A mechanism is provided to make asynchronous notifications to the maininterpreter thread. These notifications take the form of a functionpointer and a void pointer argument.

intPy_AddPendingCall(int(*func)(void*),void*arg)
Part of theStable ABI.

Schedule a function to be called from the main interpreter thread. Onsuccess,0 is returned andfunc is queued for being called in themain thread. On failure,-1 is returned without setting any exception.

When successfully queued,func will beeventually called from themain interpreter thread with the argumentarg. It will be calledasynchronously with respect to normally running Python code, but withboth these conditions met:

func must return0 on success, or-1 on failure with an exceptionset.func won’t be interrupted to perform another asynchronousnotification recursively, but it can still be interrupted to switchthreads if thethread state is detached.

This function doesn’t need anattached thread state. However, to call thisfunction in a subinterpreter, the caller must have anattached thread state.Otherwise, the functionfunc can be scheduled to be called from the wrong interpreter.

Warning

This is a low-level function, only useful for very special cases.There is no guarantee thatfunc will be called as quick aspossible. If the main thread is busy executing a system call,func won’t be called before the system call returns. Thisfunction is generallynot suitable for calling Python code fromarbitrary C threads. Instead, use thePyGILState API.

Added in version 3.1.

Changed in version 3.9:If this function is called in a subinterpreter, the functionfunc isnow scheduled to be called from the subinterpreter, rather than beingcalled from the main interpreter. Each subinterpreter now has its ownlist of scheduled calls.

Changed in version 3.12:This function now always schedulesfunc to be run in the maininterpreter.

intPy_MakePendingCalls(void)
Part of theStable ABI.

Execute all pending calls. This is usually executed automatically by theinterpreter.

This function returns0 on success, and returns-1 with an exceptionset on failure.

If this is not called in the main thread of the maininterpreter, this function does nothing and returns0.The caller must hold anattached thread state.

Added in version 3.1.

Changed in version 3.12:This function only runs pending calls in the main interpreter.

intPyThreadState_SetAsyncExc(unsignedlongid,PyObject*exc)
Part of theStable ABI.

Asynchronously raise an exception in a thread. Theid argument is the threadid of the target thread;exc is the exception object to be raised. Thisfunction does not steal any references toexc. To prevent naive misuse, youmust write your own C extension to call this. Must be called with anattached thread state.Returns the number of thread states modified; this is normally one, but will bezero if the thread id isn’t found. Ifexc isNULL, the pendingexception (if any) for the thread is cleared. This raises no exceptions.

Changed in version 3.7:The type of theid parameter changed fromlong tounsignedlong.

Operating system thread APIs

PYTHREAD_INVALID_THREAD_ID

Sentinel value for an invalid thread ID.

This is currently equivalent to(unsignedlong)-1.

unsignedlongPyThread_start_new_thread(void(*func)(void*),void*arg)
Part of theStable ABI.

Start functionfunc in a new thread with argumentarg.The resulting thread is not intended to be joined.

func must not beNULL, butarg may beNULL.

On success, this function returns the identifier of the new thread; on failure,this returnsPYTHREAD_INVALID_THREAD_ID.

The caller does not need to hold anattached thread state.

unsignedlongPyThread_get_thread_ident(void)
Part of theStable ABI.

Return the identifier of the current thread, which will never be zero.

This function cannot fail, and the caller does not need to hold anattached thread state.

PyObject*PyThread_GetInfo(void)
Part of theStable ABI since version 3.3.

Get general information about the current thread in the form of astruct sequence object. This information isaccessible assys.thread_info in Python.

On success, this returns a newstrong reference to the threadinformation; on failure, this returnsNULL with an exception set.

The caller must hold anattached thread state.

PY_HAVE_THREAD_NATIVE_ID

This macro is defined when the system supports native thread IDs.

unsignedlongPyThread_get_thread_native_id(void)
Part of theStable ABI on platforms with native thread IDs.

Get the native identifier of the current thread as it was assigned by the operatingsystem’s kernel, which will never be less than zero.

This function is only available whenPY_HAVE_THREAD_NATIVE_ID isdefined.

This function cannot fail, and the caller does not need to hold anattached thread state.

voidPyThread_exit_thread(void)
Part of theStable ABI.

Terminate the current thread. This function is generally considered unsafeand should be avoided. It is kept solely for backwards compatibility.

This function is only safe to call if all functions in the full callstack are written to safely allow it.

Warning

If the current system uses POSIX threads (also known as “pthreads”),this callspthread_exit(3), which attempts to unwind the stackand call C++ destructors on some libc implementations. However, if anoexcept function is reached, it may terminate the process.Other systems, such as macOS, do unwinding.

On Windows, this function calls_endthreadex(), which kills the threadwithout calling C++ destructors.

In any case, there is a risk of corruption on the thread’s stack.

Deprecated since version 3.14.

voidPyThread_init_thread(void)
Part of theStable ABI.

InitializePyThread* APIs. Python executes this function automatically,so there’s little need to call it from an extension module.

intPyThread_set_stacksize(size_tsize)
Part of theStable ABI.

Set the stack size of the current thread tosize bytes.

This function returns0 on success,-1 ifsize is invalid, or-2 if the system does not support changing the stack size. This functiondoes not set exceptions.

The caller does not need to hold anattached thread state.

size_tPyThread_get_stacksize(void)
Part of theStable ABI.

Return the stack size of the current thread in bytes, or0 if the system’sdefault stack size is in use.

The caller does not need to hold anattached thread state.