@@ -1441,6 +1441,109 @@ application).
14411441 list appear empty for the duration, and raises :exc: `ValueError ` if it can
14421442 detect that the list has been mutated during a sort.
14431443
1444+ .. admonition :: Thread safety
1445+
1446+ Reading a single element from a :class: `list ` is
1447+ :term: `atomic <atomic operation> `:
1448+
1449+ .. code-block ::
1450+ :class: green
1451+
1452+ lst[i] # list.__getitem__
1453+
1454+ The following methods traverse the list and use :term: `atomic <atomic operation> `
1455+ reads of each item to perform their function. That means that they may
1456+ return results affected by concurrent modifications:
1457+
1458+ .. code-block ::
1459+ :class: maybe
1460+
1461+ item in lst
1462+ lst.index(item)
1463+ lst.count(item)
1464+
1465+ All of the above methods/operations are also lock-free. They do not block
1466+ concurrent modifications. Other operations that hold a lock will not block
1467+ these from observing intermediate states.
1468+
1469+ All other operations from here on block using the per-object lock.
1470+
1471+ Writing a single item via ``lst[i] = x `` is safe to call from multiple
1472+ threads and will not corrupt the list.
1473+
1474+ The following operations return new objects and appear
1475+ :term: `atomic <atomic operation> ` to other threads:
1476+
1477+ .. code-block ::
1478+ :class: good
1479+
1480+ lst1 + lst2 # concatenates two lists into a new list
1481+ x * lst # repeats lst x times into a new list
1482+ lst.copy() # returns a shallow copy of the list
1483+
1484+ Methods that only operate on a single elements with no shifting required are
1485+ :term: `atomic <atomic operation> `:
1486+
1487+ .. code-block ::
1488+ :class: good
1489+
1490+ lst.append(x) # append to the end of the list, no shifting required
1491+ lst.pop() # pop element from the end of the list, no shifting required
1492+
1493+ The :meth: `~list.clear ` method is also :term: `atomic <atomic operation> `.
1494+ Other threads cannot observe elements being removed.
1495+
1496+ The :meth: `~list.sort ` method is not :term: `atomic <atomic operation> `.
1497+ Other threads cannot observe intermediate states during sorting, but the
1498+ list appears empty for the duration of the sort.
1499+
1500+ The following operations may allow lock-free operations to observe
1501+ intermediate states since they modify multiple elements in place:
1502+
1503+ .. code-block ::
1504+ :class: maybe
1505+
1506+ lst.insert(idx, item) # shifts elements
1507+ lst.pop(idx) # idx not at the end of the list, shifts elements
1508+ lst *= x # copies elements in place
1509+
1510+ The :meth: `~list.remove ` method may allow concurrent modifications since
1511+ element comparison may execute arbitrary Python code (via
1512+ :meth: `~object.__eq__ `).
1513+
1514+ :meth: `~list.extend ` is safe to call from multiple threads. However, its
1515+ guarantees depend on the iterable passed to it. If it is a :class: `list `, a
1516+ :class: `tuple `, a :class: `set `, a :class: `frozenset `, a :class: `dict ` or a
1517+ :ref: `dictionary view object <dict-views >` (but not their subclasses), the
1518+ ``extend `` operation is safe from concurrent modifications to the iterable.
1519+ Otherwise, an iterator is created which can be concurrently modified by
1520+ another thread. The same applies to inplace concatenation of a list with
1521+ other iterables when using ``lst += iterable ``.
1522+
1523+ Similarly, assigning to a list slice with ``lst[i:j] = iterable `` is safe
1524+ to call from multiple threads, but ``iterable `` is only locked when it is
1525+ also a :class: `list ` (but not its subclasses).
1526+
1527+ Operations that involve multiple accesses, as well as iteration, are never
1528+ atomic. For example:
1529+
1530+ .. code-block ::
1531+ :class: bad
1532+
1533+ # NOT atomic: read-modify-write
1534+ lst[i] = lst[i] + 1
1535+
1536+ # NOT atomic: check-then-act
1537+ if lst:
1538+ item = lst.pop()
1539+
1540+ # NOT thread-safe: iteration while modifying
1541+ for item in lst:
1542+ process(item) # another thread may modify lst
1543+
1544+ Consider external synchronization when sharing :class: `list ` instances
1545+ across threads. See :ref: `freethreading-python-howto ` for more information.
1546+
14441547
14451548.. _typesseq-tuple :
14461549
0 commit comments