Skip to content

Commit d60f2e2

Browse files
committed
Add documentation note.
1 parent 8bb980f commit d60f2e2

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

Doc/library/ctypes.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,35 @@ invalid non-\ ``NULL`` pointers would crash Python)::
870870
ValueError: NULL pointer access
871871
>>>
872872

873+
.. _ctypes-thread-safety:
874+
875+
Thread Safety Without The GIL
876+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
877+
878+
In Python 3.13, the :term:`GIL` may be disabled on :term:`experimental free threaded <free threading>` builds.
879+
In ctypes, reads and writes to a single object concurrently is safe, but not across multiple objects.::
880+
881+
>>> number = c_int(42)
882+
>>> pointer_a = pointer(number)
883+
>>> pointer_b = pointer(number)
884+
885+
In the above, it's only safe for one object to read and write to the address at once if the :term:`GIL` is disabled.
886+
So, ``pointer_a`` can be shared and written to across multiple threads, but only if ``pointer_b``
887+
is not also attempting to do the same. If this is an issue, consider using a :class:`threading.Lock`
888+
to synchronize access to memory.::
889+
890+
>>> import threading
891+
>>> lock = threading.Lock()
892+
>>> # Thread 1
893+
>>> with lock:
894+
... pointer_a.contents = 24
895+
>>> # Thread 2
896+
>>> with lock:
897+
... pointer_b.contents = 42
898+
899+
.. seealso::
900+
901+
:func:`sys._is_gil_enabled` if you would like to dynamically synchronize your application.
873902

874903
.. _ctypes-type-conversions:
875904

0 commit comments

Comments
 (0)