|
| 1 | +.. highlight:: c |
| 2 | + |
| 3 | +Synchronization Primitives |
| 4 | +========================== |
| 5 | + |
| 6 | +The C-API provides a basic mutual exclusion lock. |
| 7 | + |
| 8 | +.. c:type:: PyMutex |
| 9 | +
|
| 10 | + A mutual exclusion lock. The :c:type:`!PyMutex` should be initialized to |
| 11 | + zero to represent the unlocked state. For example:: |
| 12 | + |
| 13 | + PyMutex mutex = {0}; |
| 14 | + |
| 15 | + Instances of :c:type:`!PyMutex` should not be copied or moved. Both the |
| 16 | + contents and address of a :c:type:`!PyMutex` are meaningful, and it must |
| 17 | + remain at a fixed, writable location in memory. |
| 18 | + |
| 19 | + .. note:: |
| 20 | + |
| 21 | + A :c:type:`!PyMutex` currently occupies one byte, but the size should be |
| 22 | + considered unstable. The size may change in future Python releases |
| 23 | + without a deprecation period. |
| 24 | + |
| 25 | + .. versionadded:: 3.13 |
| 26 | + |
| 27 | +.. c:function:: void PyMutex_Lock(PyMutex *m) |
| 28 | +
|
| 29 | + Lock mutex *m*. If another thread has already locked it, the calling |
| 30 | + thread will block until the mutex is unlocked. While blocked, the thread |
| 31 | + will temporarily detach the :term:`thread state <attached thread state>` if one exists. |
| 32 | +
|
| 33 | + .. versionadded:: 3.13 |
| 34 | +
|
| 35 | +.. c:function:: void PyMutex_Unlock(PyMutex *m) |
| 36 | +
|
| 37 | + Unlock mutex *m*. The mutex must be locked --- otherwise, the function will |
| 38 | + issue a fatal error. |
| 39 | +
|
| 40 | + .. versionadded:: 3.13 |
| 41 | +
|
| 42 | +.. c:function:: int PyMutex_IsLocked(PyMutex *m) |
| 43 | +
|
| 44 | + Returns non-zero if the mutex *m* is currently locked, zero otherwise. |
| 45 | +
|
| 46 | + .. note:: |
| 47 | +
|
| 48 | + This function is intended for use in assertions and debugging only and |
| 49 | + should not be used to make concurrency control decisions, as the lock |
| 50 | + state may change immediately after the check. |
| 51 | +
|
| 52 | + .. versionadded:: 3.14 |
| 53 | +
|
| 54 | +.. _python-critical-section-api: |
| 55 | +
|
| 56 | +Python Critical Section API |
| 57 | +--------------------------- |
| 58 | +
|
| 59 | +The critical section API provides a deadlock avoidance layer on top of |
| 60 | +per-object locks for :term:`free-threaded <free threading>` CPython. They are |
| 61 | +intended to replace reliance on the :term:`global interpreter lock`, and are |
| 62 | +no-ops in versions of Python with the global interpreter lock. |
| 63 | +
|
| 64 | +Critical sections are intended to be used for custom types implemented |
| 65 | +in C-API extensions. They should generally not be used with built-in types like |
| 66 | +:class:`list` and :class:`dict` because their public C-APIs |
| 67 | +already use critical sections internally, with the notable |
| 68 | +exception of :c:func:`PyDict_Next`, which requires critical section |
| 69 | +to be acquired externally. |
| 70 | +
|
| 71 | +Critical sections avoid deadlocks by implicitly suspending active critical |
| 72 | +sections, hence, they do not provide exclusive access such as provided by |
| 73 | +traditional locks like :c:type:`PyMutex`. When a critical section is started, |
| 74 | +the per-object lock for the object is acquired. If the code executed inside the |
| 75 | +critical section calls C-API functions then it can suspend the critical section thereby |
| 76 | +releasing the per-object lock, so other threads can acquire the per-object lock |
| 77 | +for the same object. |
| 78 | +
|
| 79 | +Variants that accept :c:type:`PyMutex` pointers rather than Python objects are also |
| 80 | +available. Use these variants to start a critical section in a situation where |
| 81 | +there is no :c:type:`PyObject` -- for example, when working with a C type that |
| 82 | +does not extend or wrap :c:type:`PyObject` but still needs to call into the C |
| 83 | +API in a manner that might lead to deadlocks. |
| 84 | +
|
| 85 | +The functions and structs used by the macros are exposed for cases |
| 86 | +where C macros are not available. They should only be used as in the |
| 87 | +given macro expansions. Note that the sizes and contents of the structures may |
| 88 | +change in future Python versions. |
| 89 | +
|
| 90 | +.. note:: |
| 91 | +
|
| 92 | + Operations that need to lock two objects at once must use |
| 93 | + :c:macro:`Py_BEGIN_CRITICAL_SECTION2`. You *cannot* use nested critical |
| 94 | + sections to lock more than one object at once, because the inner critical |
| 95 | + section may suspend the outer critical sections. This API does not provide |
| 96 | + a way to lock more than two objects at once. |
| 97 | +
|
| 98 | +Example usage:: |
| 99 | +
|
| 100 | + static PyObject * |
| 101 | + set_field(MyObject *self, PyObject *value) |
| 102 | + { |
| 103 | + Py_BEGIN_CRITICAL_SECTION(self); |
| 104 | + Py_SETREF(self->field, Py_XNewRef(value)); |
| 105 | + Py_END_CRITICAL_SECTION(); |
| 106 | + Py_RETURN_NONE; |
| 107 | + } |
| 108 | +
|
| 109 | +In the above example, :c:macro:`Py_SETREF` calls :c:macro:`Py_DECREF`, which |
| 110 | +can call arbitrary code through an object's deallocation function. The critical |
| 111 | +section API avoids potential deadlocks due to reentrancy and lock ordering |
| 112 | +by allowing the runtime to temporarily suspend the critical section if the |
| 113 | +code triggered by the finalizer blocks and calls :c:func:`PyEval_SaveThread`. |
| 114 | +
|
| 115 | +.. c:macro:: Py_BEGIN_CRITICAL_SECTION(op) |
| 116 | +
|
| 117 | + Acquires the per-object lock for the object *op* and begins a |
| 118 | + critical section. |
| 119 | +
|
| 120 | + In the free-threaded build, this macro expands to:: |
| 121 | +
|
| 122 | + { |
| 123 | + PyCriticalSection _py_cs; |
| 124 | + PyCriticalSection_Begin(&_py_cs, (PyObject*)(op)) |
| 125 | +
|
| 126 | + In the default build, this macro expands to ``{``. |
| 127 | +
|
| 128 | + .. versionadded:: 3.13 |
| 129 | +
|
| 130 | +.. c:macro:: Py_BEGIN_CRITICAL_SECTION_MUTEX(m) |
| 131 | +
|
| 132 | + Locks the mutex *m* and begins a critical section. |
| 133 | +
|
| 134 | + In the free-threaded build, this macro expands to:: |
| 135 | +
|
| 136 | + { |
| 137 | + PyCriticalSection _py_cs; |
| 138 | + PyCriticalSection_BeginMutex(&_py_cs, m) |
| 139 | +
|
| 140 | + Note that unlike :c:macro:`Py_BEGIN_CRITICAL_SECTION`, there is no cast for |
| 141 | + the argument of the macro - it must be a :c:type:`PyMutex` pointer. |
| 142 | +
|
| 143 | + On the default build, this macro expands to ``{``. |
| 144 | +
|
| 145 | + .. versionadded:: 3.14 |
| 146 | +
|
| 147 | +.. c:macro:: Py_END_CRITICAL_SECTION() |
| 148 | +
|
| 149 | + Ends the critical section and releases the per-object lock. |
| 150 | +
|
| 151 | + In the free-threaded build, this macro expands to:: |
| 152 | +
|
| 153 | + PyCriticalSection_End(&_py_cs); |
| 154 | + } |
| 155 | +
|
| 156 | + In the default build, this macro expands to ``}``. |
| 157 | +
|
| 158 | + .. versionadded:: 3.13 |
| 159 | +
|
| 160 | +.. c:macro:: Py_BEGIN_CRITICAL_SECTION2(a, b) |
| 161 | +
|
| 162 | + Acquires the per-objects locks for the objects *a* and *b* and begins a |
| 163 | + critical section. The locks are acquired in a consistent order (lowest |
| 164 | + address first) to avoid lock ordering deadlocks. |
| 165 | +
|
| 166 | + In the free-threaded build, this macro expands to:: |
| 167 | +
|
| 168 | + { |
| 169 | + PyCriticalSection2 _py_cs2; |
| 170 | + PyCriticalSection2_Begin(&_py_cs2, (PyObject*)(a), (PyObject*)(b)) |
| 171 | +
|
| 172 | + In the default build, this macro expands to ``{``. |
| 173 | +
|
| 174 | + .. versionadded:: 3.13 |
| 175 | +
|
| 176 | +.. c:macro:: Py_BEGIN_CRITICAL_SECTION2_MUTEX(m1, m2) |
| 177 | +
|
| 178 | + Locks the mutexes *m1* and *m2* and begins a critical section. |
| 179 | +
|
| 180 | + In the free-threaded build, this macro expands to:: |
| 181 | +
|
| 182 | + { |
| 183 | + PyCriticalSection2 _py_cs2; |
| 184 | + PyCriticalSection2_BeginMutex(&_py_cs2, m1, m2) |
| 185 | +
|
| 186 | + Note that unlike :c:macro:`Py_BEGIN_CRITICAL_SECTION2`, there is no cast for |
| 187 | + the arguments of the macro - they must be :c:type:`PyMutex` pointers. |
| 188 | +
|
| 189 | + On the default build, this macro expands to ``{``. |
| 190 | +
|
| 191 | + .. versionadded:: 3.14 |
| 192 | +
|
| 193 | +.. c:macro:: Py_END_CRITICAL_SECTION2() |
| 194 | +
|
| 195 | + Ends the critical section and releases the per-object locks. |
| 196 | +
|
| 197 | + In the free-threaded build, this macro expands to:: |
| 198 | +
|
| 199 | + PyCriticalSection2_End(&_py_cs2); |
| 200 | + } |
| 201 | +
|
| 202 | + In the default build, this macro expands to ``}``. |
| 203 | +
|
| 204 | + .. versionadded:: 3.13 |
| 205 | +
|
| 206 | +
|
| 207 | +Legacy Locking APIs |
| 208 | +------------------- |
| 209 | +
|
| 210 | +These APIs are obsolete since Python 3.13 with the introduction of |
| 211 | +:c:type:`PyMutex`. |
| 212 | +
|
| 213 | +.. versionchanged:: 3.15 |
| 214 | + These APIs are now a simple wrapper around ``PyMutex``. |
| 215 | +
|
| 216 | +
|
| 217 | +.. c:type:: PyThread_type_lock |
| 218 | +
|
| 219 | + A pointer to a mutual exclusion lock. |
| 220 | +
|
| 221 | +
|
| 222 | +.. c:type:: PyLockStatus |
| 223 | +
|
| 224 | + The result of acquiring a lock with a timeout. |
| 225 | +
|
| 226 | + .. c:namespace:: NULL |
| 227 | +
|
| 228 | + .. c:enumerator:: PY_LOCK_FAILURE |
| 229 | +
|
| 230 | + Failed to acquire the lock. |
| 231 | +
|
| 232 | + .. c:enumerator:: PY_LOCK_ACQUIRED |
| 233 | +
|
| 234 | + The lock was successfully acquired. |
| 235 | +
|
| 236 | + .. c:enumerator:: PY_LOCK_INTR |
| 237 | +
|
| 238 | + The lock was interrupted by a signal. |
| 239 | +
|
| 240 | +
|
| 241 | +.. c:function:: PyThread_type_lock PyThread_allocate_lock(void) |
| 242 | +
|
| 243 | + Allocate a new lock. |
| 244 | +
|
| 245 | + On success, this function returns a lock; on failure, this |
| 246 | + function returns ``0`` without an exception set. |
| 247 | +
|
| 248 | + The caller does not need to hold an :term:`attached thread state`. |
| 249 | +
|
| 250 | + .. versionchanged:: 3.15 |
| 251 | + This function now always uses :c:type:`PyMutex`. In prior versions, this |
| 252 | + would use a lock provided by the operating system. |
| 253 | +
|
| 254 | +
|
| 255 | +.. c:function:: void PyThread_free_lock(PyThread_type_lock lock) |
| 256 | +
|
| 257 | + Destroy *lock*. The lock should not be held by any thread when calling |
| 258 | + this. |
| 259 | +
|
| 260 | + The caller does not need to hold an :term:`attached thread state`. |
| 261 | +
|
| 262 | +
|
| 263 | +.. c:function:: PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock lock, long long microseconds, int intr_flag) |
| 264 | +
|
| 265 | + Acquire *lock* with a timeout. |
| 266 | +
|
| 267 | + This will wait for *microseconds* microseconds to acquire the lock. If the |
| 268 | + timeout expires, this function returns :c:enumerator:`PY_LOCK_FAILURE`. |
| 269 | + If *microseconds* is ``-1``, this will wait indefinitely until the lock has |
| 270 | + been released. |
| 271 | +
|
| 272 | + If *intr_flag* is ``1``, acquiring the lock may be interrupted by a signal, |
| 273 | + in which case this function returns :c:enumerator:`PY_LOCK_INTR`. Upon |
| 274 | + interruption, it's generally expected that the caller makes a call to |
| 275 | + :c:func:`Py_MakePendingCalls` to propagate an exception to Python code. |
| 276 | +
|
| 277 | + If the lock is successfully acquired, this function returns |
| 278 | + :c:enumerator:`PY_LOCK_ACQUIRED`. |
| 279 | +
|
| 280 | + The caller does not need to hold an :term:`attached thread state`. |
| 281 | +
|
| 282 | +
|
| 283 | +.. c:function:: int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) |
| 284 | +
|
| 285 | + Acquire *lock*. |
| 286 | +
|
| 287 | + If *waitflag* is ``1`` and another thread currently holds the lock, this |
| 288 | + function will wait until the lock can be acquired and will always return |
| 289 | + ``1``. |
| 290 | +
|
| 291 | + If *waitflag* is ``0`` and another thread holds the lock, this function will |
| 292 | + not wait and instead return ``0``. If the lock is not held by any other |
| 293 | + thread, then this function will acquire it and return ``1``. |
| 294 | +
|
| 295 | + Unlike :c:func:`PyThread_acquire_lock_timed`, acquiring the lock cannot be |
| 296 | + interrupted by a signal. |
| 297 | +
|
| 298 | + The caller does not need to hold an :term:`attached thread state`. |
| 299 | +
|
| 300 | +
|
| 301 | +.. c:function:: int PyThread_release_lock(PyThread_type_lock lock) |
| 302 | +
|
| 303 | + Release *lock*. If *lock* is not held, then this function issues a |
| 304 | + fatal error. |
| 305 | +
|
| 306 | + The caller does not need to hold an :term:`attached thread state`. |
0 commit comments