🌐 AI搜索 & 代理 主页
Skip to content

Commit 38483c9

Browse files
committed
Address feedback; add more details
1 parent fd400f0 commit 38483c9

File tree

1 file changed

+70
-43
lines changed

1 file changed

+70
-43
lines changed

Doc/library/stdtypes.rst

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,49 +1369,6 @@ Lists are mutable sequences, typically used to store collections of
13691369
homogeneous items (where the precise degree of similarity will vary by
13701370
application).
13711371

1372-
.. note::
1373-
1374-
Individual operations on :class:`list` instances such as
1375-
:meth:`~list.append`, :meth:`~list.pop`, ``lst[i] = x``, and ``x = lst[i]``
1376-
are atomic and will not corrupt the list or crash when called concurrently
1377-
from multiple threads:
1378-
1379-
.. code-block::
1380-
:class: good
1381-
1382-
# These operations are safe to call concurrently from multiple threads
1383-
lst.append(item) # atomically appends item
1384-
lst.pop() # atomically removes and returns last item
1385-
lst[i] = value # atomically replaces item at index i
1386-
item = lst[i] # atomically retrieves item at index i
1387-
1388-
One exception to this rule is :meth:`~list.extend`. Its atomicity
1389-
guarantees depend on the iterable being passed. When the iterable is
1390-
a :class:`list`, a :class:`tuple`, a :class:`set`, a :class:`frozenset`,
1391-
a :class:`dict` or a :ref:`dictionary view object <dict-views>`, the
1392-
operation is atomic. Otherwise, an iterator is created which can be
1393-
concurrently modified by another thread.
1394-
1395-
Operations that involve multiple accesses, as well as iteration, are not
1396-
atomic. For example, the following patterns are not thread-safe:
1397-
1398-
.. code-block::
1399-
:class: bad
1400-
1401-
# NOT atomic: read-modify-write
1402-
lst[i] = lst[i] + 1
1403-
1404-
# NOT atomic: check-then-act
1405-
if lst:
1406-
item = lst.pop()
1407-
1408-
# NOT thread-safe: iteration while modifying
1409-
for item in lst:
1410-
process(item) # another thread may modify lst
1411-
1412-
Consider external synchronization when sharing :class:`list` instances
1413-
across threads. See :ref:`freethreading-python-howto` for more information.
1414-
14151372
.. class:: list(iterable=(), /)
14161373

14171374
Lists may be constructed in several ways:
@@ -1479,6 +1436,76 @@ application).
14791436
list appear empty for the duration, and raises :exc:`ValueError` if it can
14801437
detect that the list has been mutated during a sort.
14811438

1439+
.. admonition:: Thread safety
1440+
1441+
Most individual operations on :class:`list` instances are atomic:
1442+
1443+
.. code-block::
1444+
:class: good
1445+
1446+
# The following operations are atomic
1447+
lst1 + lst2 # atomic concatenation of two lists
1448+
x * lst # atomic repeat of lst x times
1449+
item = lst[i] # atomically retrieves item at index i
1450+
lst[i] = value # atomically replaces item at index i
1451+
lst *= x # atomically extend the list x times
1452+
1453+
# Calls to the following list methods are atomic
1454+
lst.clear()
1455+
lst.copy()
1456+
lst.append(item)
1457+
lst.insert(idx, item)
1458+
lst.pop(idx)
1459+
lst.remove(item)
1460+
lst.reverse()
1461+
lst.sort()
1462+
1463+
The following operations/methods are not atomic:
1464+
1465+
.. code-block::
1466+
:class: maybe
1467+
1468+
lst.index(item)
1469+
lst.count(item)
1470+
item in lst
1471+
1472+
The :meth:`~list.index` and :meth:`~list.count` methods, and the ``in``
1473+
operator, iterate the list without holding a lock. They are safe to call
1474+
concurrently but may return results affected by concurrent modifications.
1475+
1476+
:meth:`~list.extend` is always atomic with respect to the target list.
1477+
However, the operation is fully atomic only when the iterable that's passed
1478+
to ``extend`` is a :class:`list`, a :class:`tuple`, a :class:`set`, a
1479+
:class:`frozenset`, a :class:`dict` or a
1480+
:ref:`dictionary view object <dict-views>`. Otherwise, an iterator is
1481+
created which can be concurrently modified by another thread. The same
1482+
applies to inplace concatenation of list with other iterables when using
1483+
``lst += iterable``.
1484+
1485+
Similarly, assigning to a list slice with ``lst[i:j] = obj`` is always
1486+
atomic with respect to the target list, but ``obj`` is only locked when it
1487+
is also a :class:`list`.
1488+
1489+
Operations that involve multiple accesses, as well as iteration, are not
1490+
atomic. For example:
1491+
1492+
.. code-block::
1493+
:class: bad
1494+
1495+
# NOT atomic: read-modify-write
1496+
lst[i] = lst[i] + 1
1497+
1498+
# NOT atomic: check-then-act
1499+
if lst:
1500+
item = lst.pop()
1501+
1502+
# NOT thread-safe: iteration while modifying
1503+
for item in lst:
1504+
process(item) # another thread may modify lst
1505+
1506+
Consider external synchronization when sharing :class:`list` instances
1507+
across threads. See :ref:`freethreading-python-howto` for more information.
1508+
14821509

14831510
.. _typesseq-tuple:
14841511

0 commit comments

Comments
 (0)