Skip to content

Commit 49a2e66

Browse files
markshannonhugovk
andauthored
Apply Hugo's format fixes and spelling corrections
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
1 parent 1aa961c commit 49a2e66

1 file changed

Lines changed: 23 additions & 34 deletions

File tree

peps/pep-0805.rst

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Author: Mark Shannon <mark@hotpy.org>
44
Discussions-To: Pending
55
Status: Draft
66
Type: Standards Track
7-
Created: 08-Sep-2025
7+
Python-Version: 3.15
88

99
Abstract
1010
========
@@ -23,11 +23,11 @@ Traditionally, CPython has executed in only a single thread of execution at once
2323
This has always been seen as a limitation of Python and there has been a desire for
2424
Python to support parallel execution for many years.
2525

26-
PEP 703, Making the Global Interpreter Lock Optional in CPython, and PEP 554, Multiple Interpreters in the Stdlib, offer ways to support parallelism.
26+
:pep:`703`, Making the Global Interpreter Lock Optional in CPython, and :pep:`554`, Multiple Interpreters in the Stdlib, offer ways to support parallelism.
2727
Multiple interpreters are both safe and support parallelism, but they are difficult to use and sharing objects
2828
between multiple interpreters without copying is impossible.
2929
PEP 703 supports parallel execution and sharing, but is unsafe as it allows race conditions.
30-
Race conditions allow dangerous and hard to find bugs. In the most extreme example, Therac-25 [1]_, a race condition bug resulted in several fatalities. The trouble with race conditions is not that the bugs they introduce are necessarily worse than other bugs,
30+
Race conditions allow dangerous and hard to find bugs. In the most extreme example, `Therac-25 <https://en.wikipedia.org/wiki/Therac-25>`__, a race condition bug resulted in several fatalities. The trouble with race conditions is not that the bugs they introduce are necessarily worse than other bugs,
3131
but that they can be very hard to detect and may easily slip through testing.
3232

3333
Parallelism, without strong support from the language and runtime, is extremely difficult to get right:
@@ -71,7 +71,7 @@ The PEP also proposes changes to CPython to prevent unsafe execution when mutabl
7171
Finally, the PEP provides a generalization of the GIL to allow incrementally moving away from the GIL.
7272

7373
This PEP is inspired by ideas from OCaml, specifically Data Freedom à la Mode [2]_, and the Pyrona project [3]_.
74-
Many of the necessary technologies, such as biased and deferred reference counting, have been developed for PEP 703.
74+
Many of the necessary technologies, such as biased and deferred reference counting, have been developed for :pep:`703`.
7575

7676
Specification
7777
=============
@@ -85,7 +85,7 @@ The state can be queried by looking at the ``__shared__`` attribute of an object
8585
An object's ``__shared__`` state can be one of the following:
8686

8787
* Immutable: Cannot be modified, and can be safely shared between threads.
88-
* Local: Only visible to a single thread<sup>*</sup>, and can be freely mutated by that thread.
88+
* Local: Only visible to a single thread\ :sup:`*`, and can be freely mutated by that thread.
8989
* Stop-the-world mutable. Mostly immutable, but can be mutated by acquiring the stop-the-world lock.
9090
* Protected: Object is mutable, and is protected by a mutex.
9191
* Synchronized: A special state for some builtin objects.
@@ -98,14 +98,14 @@ The ``__shared__`` attribute is read-only.
9898
All classes, modules and functions will be *stop-the-world mutable* initially, but can be made *immutable*.
9999
Views, iterators and other objects that depend on the internal state of other mutable objects will inherit the state of
100100
those objects. For example, a ``listiterator`` of a *local* ``list`` will be *local*, but a ``listiterator`` of a *protected*
101-
``list`` will be *protected*. Views and iterators of *immutable* (including STW mutable) objects will be *local* when created.
101+
``list`` will be *protected*. Views and iterators of *immutable* (including stop-the-world mutable) objects will be *local* when created.
102102

103103
All objects that are not inherently immutable (like tuples or strings) will be created as *local*.
104104
These *local* objects can later be made *immutable* or *protected*.
105105

106106
Dictionaries and lists will support the ability to be made stop-the-world mutable on a per-object basis.
107107
This is to maintain the necessary immutability for performance and mutability for
108-
backwards campatibility for objects like ``sys.modules`` and ``sys.path``.
108+
backwards compatibility for objects like ``sys.modules`` and ``sys.path``.
109109

110110
The stop-the-world lock
111111
-----------------------
@@ -123,11 +123,11 @@ SuperThread objects
123123
A new class ``SuperThread`` will be added to help port applications using the GIL
124124
and sub-interpreters. All threads sharing a ``SuperThread`` will be serialized,
125125
in the same way as all threads are currently serialized by the GIL.
126-
``SuperThread``\ s offer much the same capabilites as sub-interpreters,
126+
``SuperThread``\ s offer much the same capabilities as sub-interpreters,
127127
but more efficiently and with the ability to share more objects.
128128

129129
There is a many-to-one relationship between threads and ``SuperThread``\ s.
130-
If no super thread is explictly specified when creating a thread,
130+
If no super thread is explicitly specified when creating a thread,
131131
a new super thread will be created specifically for that thread.
132132
The super thread of a thread cannot be changed.
133133

@@ -215,7 +215,7 @@ Passing mutable values between threads
215215
''''''''''''''''''''''''''''''''''''''
216216

217217
The ``Channel`` class is provided for passing objects from one thread to another.
218-
The ``Channel`` class acts like a ``deque`` but handles tranferring of ownership local objects.
218+
The ``Channel`` class acts like a ``deque`` but handles transferring of ownership local objects.
219219
When passing a *local* object, ``channel.put(obj)`` detaches the object ``obj`` from the current thread.
220220
When passing a *local* object, ``Channel.put()`` will fail, raising a ``ValueError``, if there are any other references to the argument.
221221
``Channel.get()`` returns the object passed but to ``Channel.put()``, making the calling
@@ -234,7 +234,7 @@ the ``sys`` module is deleted. The main thread's ``SuperThread`` will be the GIL
234234

235235
If the environment variable ``PYTHONGIL=1`` is set, then all new threads will default to
236236
``super_thread = sys.gil``. Otherwise all new threads will default to ``super_thread = None``.
237-
Explictly setting the ``super_thread`` argument when creating a thread will override these defaults.
237+
Explicitly setting the ``super_thread`` argument when creating a thread will override these defaults.
238238

239239
Deadlock detection
240240
------------------
@@ -265,14 +265,14 @@ If we do that, then all other operations become safe.
265265
| All other operations | Yes | Yes | N/A | Yes | Yes |
266266
+------------------------+-----------+-----------------+-----------------+---------------+----------------+
267267

268-
1. If the mutex held by the thread matches the mutex that protects the object
268+
1. If the mutex held by the thread matches the mutex that protects the object.
269269
2. If supported for that class.
270270
3. The argument to ``__protect__`` must the sole reference to the object.
271271

272272
ABI breakage
273273
------------
274274

275-
This PEP will require a one time ABI breakage, much like PEP 703, as the ``PyObject`` struct will need to be changed.
275+
This PEP will require a one time ABI breakage, much like :pep:`703`, as the ``PyObject`` struct will need to be changed.
276276

277277
Deferred reclamation
278278
--------------------
@@ -282,7 +282,7 @@ In other words, they may not be reclaimed immediately that their are no more ref
282282

283283
This is because these objects may be referred to from several threads simultaneously, and the overhead
284284
of serializing the reference count operations would be too high.
285-
PEP 703 also does this.
285+
:pep:`703` also does this.
286286

287287
Local objects, visible to only one thread, will still be reclaimed immediately that they are no longer referenced.
288288

@@ -370,7 +370,7 @@ How to Teach This
370370
=================
371371

372372
In order to run code in parallel, some understanding of the model of execution will
373-
be needed. Writing unsafe code is much harder than under PEP 703, but the
373+
be needed. Writing unsafe code is much harder than under :pep:`703`, but the
374374
new exceptions may surprise users. Extensive documentation will be needed.
375375

376376
Examples
@@ -444,7 +444,7 @@ inherits the protection from the ``list`` object.
444444
Comparison to PEP 703 (Making the Global Interpreter Lock Optional in CPython)
445445
==============================================================================
446446

447-
This PEP should be thought of as building on PEP 703, rather than competing with or replacing it.
447+
This PEP should be thought of as building on :pep:`703`, rather than competing with or replacing it.
448448
Many of the mechanisms needed to implement this PEP have been developed for PEP 703.
449449

450450
What PEP 703 lacks is well defined semantics for what happens when race conditions are present,
@@ -454,10 +454,10 @@ PEP 703 attempts to provide single-threaded performance for lists, dictionaries,
454454
and other mutable objects while providing "reasonable" thread safety. Unfortunately,
455455
no formal definition of expected behavior is provided, which leads to issues like these:
456456

457-
* <https://github.com/python/cpython/issues/129619>
458-
* <https://github.com/python/cpython/issues/129139>
459-
* <https://github.com/python/cpython/issues/126559>
460-
* <https://github.com/python/cpython/issues/130744>
457+
* `python/cpython#129619 <https://github.com/python/cpython/issues/129619>`__
458+
* `python/cpython#129139 <https://github.com/python/cpython/issues/129139>`__
459+
* `python/cpython#126559 <https://github.com/python/cpython/issues/126559>`__
460+
* `python/cpython#130744 <https://github.com/python/cpython/issues/130744>`__
461461

462462
It is the author's opinion that attempting to preserve single-threaded performance
463463
for mutable objects *and* any sort of thread safe parallel execution for the same object is wishful thinking.
@@ -475,7 +475,7 @@ Object state
475475

476476
Recording object state requires space in the object header, at least 3 bits but no more than a byte.
477477
Each object also needs additional space to refer to its thread, or protecting mutex.
478-
With these fields, the ``PyObject`` header should be the smaller than is currently implemented for PEP 703,
478+
With these fields, the ``PyObject`` header should be the smaller than is currently implemented for :pep:`703`,
479479
although larger than for the default (with GIL) build.
480480

481481
A possible object header:
@@ -543,11 +543,11 @@ Possible future enhancements
543543
Deep freezing and deep transfers
544544
--------------------------------
545545

546-
Freezing a single object could leave a frozen object with references to mutable objects, and transfering of single objects could leave an object local to one thread, while other objects that it refers to are local to a different thread.
546+
Freezing a single object could leave a frozen object with references to mutable objects, and transferring of single objects could leave an object local to one thread, while other objects that it refers to are local to a different thread.
547547
Either of these scanarios are likely to lead to runtime errors. To avoid that problem we need "deep" freezing.
548548

549549
Deep freezing an object would freeze that object and the transitive closure of other mutable objects referred to by that object.
550-
Deep transfering an object would transfer that object and the transitive closure of other local objects referred to by that object,
550+
Deep transferring an object would transfer that object and the transitive closure of other local objects referred to by that object,
551551
but would raise an exception if one of the those objects belonged to a different thread.
552552

553553
Similar to freezing, a "deep" put mechanism could be added to ``Channel``\ s to move a whole graph of objects from one thread
@@ -565,17 +565,6 @@ Open Issues
565565
[Any points that are still being decided/discussed.]
566566

567567

568-
Footnotes
569-
=========
570-
571-
.. [1] https://en.wikipedia.org/wiki/Therac-25
572-
573-
.. [2] https://dl.acm.org/doi/10.1145/3704859
574-
575-
.. [3] https://wrigstad.com/pldi2025.pdf
576-
577-
578-
579568
Copyright
580569
=========
581570

0 commit comments

Comments
 (0)