執行緒狀態與全域直譯器鎖

Unless on afree-threaded build ofCPython,the Python interpreter is not fully thread-safe. In order to supportmulti-threaded Python programs, there's a global lock, called theglobalinterpreter lock orGIL, that must be held by the current thread beforeit can safely access Python objects. Without the lock, even the simplestoperations could 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.

Therefore, the rule exists that only the thread that has acquired theGIL may operate on Python objects or call Python/C API functions.In order to emulate concurrency of execution, the interpreter regularlytries to switch threads (seesys.setswitchinterval()). The lock is alsoreleased around potentially blocking I/O operations like reading or writinga file, so that other Python threads can run in the meantime.

The Python interpreter keeps some thread-specific bookkeeping informationinside a data structure calledPyThreadState, known as athread state.Each OS 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 theGIL, except onfree-threaded builds. On builds with theGIL enabled,attaching a thread state will block until theGILcan be acquired. However, even on builds with theGIL disabled, it is still requiredto have an attached thread state to call most of the C API.

In general, there will always be anattached thread state when using Python's C API.Only in some specific cases (such as in aPy_BEGIN_ALLOW_THREADS block) will thethread not have an attached thread state. If uncertain, check ifPyThreadState_GetUnchecked() returnsNULL.

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:

Theattached thread state holds theGIL for the entire interpreter. When detachingtheattached thread state, theGIL is released, allowing other threads to attacha thread state to their own thread, thus getting theGIL and can start executing.The pointer to the priorattached thread state is stored as a local variable.Upon reachingPy_END_ALLOW_THREADS, the thread state that waspreviouslyattached is passed toPyEval_RestoreThread().This function will block until another releases itsthread state,thus allowing the oldthread state to get re-attached and theC API can be called again.

Forfree-threaded builds, theGIL is normallyout of the question, but detaching thethread state is still requiredfor blocking I/O and long operations. The difference is that threads don't have to wait for theGILto be released to attach their thread state, allowing true multi-core parallelism.

備註

Calling system I/O functions is the most common use case for detachingthethread state, but it can also be useful before callinglong-running computations which don't need access to Python objects, suchas compression or cryptographic functions operating over memory buffers.For example, the standardzlib andhashlib modules detach thethread state when compressing or hashing data.

APIs

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

備註

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

Py_BEGIN_ALLOW_THREADS
穩定 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
穩定 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
穩定 ABI 的一部分.

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

Py_UNBLOCK_THREADS
穩定 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 to themand the code shown above is therefore correct. However, when threads arecreated from C (for example by a third-party library with its own threadmanagement), they don't hold theGIL, because they don't have 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 anattached thread state before you can start using the Python/CAPI. When you are done, you should detach thethread state, andfinally free it.

ThePyGILState_Ensure() andPyGILState_Release() functions doall of the above automatically. The typical idiom for calling into Pythonfrom a C thread is:

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);

Note that thePyGILState_* functions assume there is only one globalinterpreter (created automatically byPy_Initialize()). Pythonsupports the creation of additional interpreters (usingPy_NewInterpreter()), but mixing multiple interpreters and thePyGILState_* API is unsupported. This is becausePyGILState_Ensure()and similar functions default toattaching athread state for the main interpreter, meaning that the thread can't safelyinteract with the calling subinterpreter.

Supporting subinterpreters in non-Python threads

If you would like to support subinterpreters with non-Python created threads, youmust use thePyThreadState_* API instead of the traditionalPyGILState_*API.

In particular, you must store the interpreter state from the callingfunction and pass it toPyThreadState_New(), which will ensure thatthethread state is targeting the correct interpreter:

/* The return value of PyInterpreterState_Get() from the   function that created this thread. */PyInterpreterState*interp=ThreadData->interp;PyThreadState*tstate=PyThreadState_New(interp);PyThreadState_Swap(tstate);/* GIL of the subinterpreter is now held.   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();

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 物件 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
受限 API 的一部分 (做為一個不透明結構 (opaque struct)).

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

PyInterpreterState*interp

這個執行緒的直譯器狀態。

voidPyEval_InitThreads()
穩定 ABI 的一部分.

已棄用的函式,什麼也不做。

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

在 3.9 版的變更:此函式現在不會做任何事情。

在 3.7 版的變更:This function is now called byPy_Initialize(), so you don'thave to call it yourself anymore.

在 3.2 版的變更:This function cannot be called beforePy_Initialize() anymore.

在 3.9 版之後被棄用.

PyThreadState*PyEval_SaveThread()
穩定 ABI 的一部分.

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

voidPyEval_RestoreThread(PyThreadState*tstate)
穩定 ABI 的一部分.

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

備註

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.

在 3.14 版的變更:Hangs the current thread, rather than terminating it, if called while theinterpreter is finalizing.

PyThreadState*PyThreadState_Get()
穩定 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).

也請見PyThreadState_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.

在 3.13 版被加入:在 Python 3.5 到 3.12 中,此函式是私有的,被稱為_PyThreadState_UncheckedGet()

PyThreadState*PyThreadState_Swap(PyThreadState*tstate)
穩定 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.

備註

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

GIL 狀態 API

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

typePyGILState_STATE
穩定 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()
穩定 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.

警告

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.

在 3.14 版的變更:Hangs the current thread, rather than terminating it, if called while theinterpreter is finalizing.

voidPyGILState_Release(PyGILState_STATE)
穩定 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()
穩定 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.

備註

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.

備註

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

在 3.4 版被加入.

低階 API

PyThreadState*PyThreadState_New(PyInterpreterState*interp)
穩定 ABI 的一部分.

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

voidPyThreadState_Clear(PyThreadState*tstate)
穩定 ABI 的一部分.

Reset all information in athread state object.tstatemust beattached

在 3.9 版的變更:This function now calls thePyThreadState.on_delete callback.Previously, that happened inPyThreadState_Delete().

在 3.13 版的變更:PyThreadState.on_delete 回呼已被移除。

voidPyThreadState_Delete(PyThreadState*tstate)
穩定 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)
穩定 ABI 的一部分 自 3.10 版本開始.

Get the current frame of the Python thread statetstate.

Return astrong reference. ReturnNULL if no frame is currentlyexecuting.

也請見PyEval_GetFrame()

tstate must not beNULL, and must beattached.

在 3.9 版被加入.

uint64_tPyThreadState_GetID(PyThreadState*tstate)
穩定 ABI 的一部分 自 3.10 版本開始.

Get the uniquethread state identifier of the Python thread statetstate.

tstate must not beNULL, and must beattached.

在 3.9 版被加入.

PyInterpreterState*PyThreadState_GetInterpreter(PyThreadState*tstate)
穩定 ABI 的一部分 自 3.10 版本開始.

Get the interpreter of the Python thread statetstate.

tstate must not beNULL, and must beattached.

在 3.9 版被加入.

voidPyThreadState_EnterTracing(PyThreadState*tstate)

Suspend tracing and profiling in the Python thread statetstate.

Resume them using thePyThreadState_LeaveTracing() function.

在 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.

在 3.11 版被加入.

intPyUnstable_ThreadState_SetStackProtection(PyThreadState*tstate,void*stack_start_addr,size_tstack_size)
這是不穩定 API,它可能在小版本發布中沒有任何警告地被變更。

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.

若要撤銷此操作,請參見PyUnstable_ThreadState_ResetStackProtection()

在 3.15 版被加入.

voidPyUnstable_ThreadState_ResetStackProtection(PyThreadState*tstate)
這是不穩定 API,它可能在小版本發布中沒有任何警告地被變更。

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

請參見PyUnstable_ThreadState_SetStackProtection() 的說明。

在 3.15 版被加入.

PyObject*PyThreadState_GetDict()
回傳值:借用參照。穩定 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)
穩定 ABI 的一部分.

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

The calling thread must not already have anattached thread state.

備註

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.

在 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.

在 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)
穩定 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)
穩定 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.

警告

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.

在 3.1 版被加入.

在 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.

在 3.12 版的變更:This function now always schedulesfunc to be run in the maininterpreter.

intPy_MakePendingCalls(void)
穩定 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.

在 3.1 版被加入.

在 3.12 版的變更:This function only runs pending calls in the main interpreter.

intPyThreadState_SetAsyncExc(unsignedlongid,PyObject*exc)
穩定 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.

在 3.7 版的變更:The type of theid parameter changed fromlong tounsignedlong.

作業系統執行緒 API

PYTHREAD_INVALID_THREAD_ID

Sentinel value for an invalid thread ID.

目前等同於(unsignedlong)-1

unsignedlongPyThread_start_new_thread(void(*func)(void*),void*arg)
穩定 ABI 的一部分.

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

func 不能是NULL,但arg 可以是NULL

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

呼叫者不需擁有一個attached thread state

unsignedlongPyThread_get_thread_ident(void)
穩定 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)
穩定 ABI 的一部分 自 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.

呼叫者必須擁有一個attached thread state

PY_HAVE_THREAD_NATIVE_ID

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

unsignedlongPyThread_get_thread_native_id(void)
穩定 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)
穩定 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.

警告

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.

在 3.14 版之後被棄用.

voidPyThread_init_thread(void)
穩定 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)
穩定 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.

呼叫者不需擁有一個attached thread state

size_tPyThread_get_stacksize(void)
穩定 ABI 的一部分.

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

呼叫者不需擁有一個attached thread state