> **Источник:** https://python-all.ru/3.15/library/threadsafety.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# Гарантии потокобезопасности

На этой странице описаны гарантии потокобезопасности для встроенных типов в сборке Python со свободной потоковой обработкой (free-threaded build). Описанные здесь гарантии действуют при использовании Python с отключённым [GIL](https://python-all.ru/3.15/glossary.html#term-GIL) (режим свободной потоковой обработки). При включённом GIL большинство операций неявно сериализуются.

Общие рекомендации по написанию потокобезопасного кода в свободно-поточной версии Python см. в разделе [Поддержка свободной потоковой обработки в Python](https://python-all.ru/3.15/howto/free-threading-python.html#freethreading-python-howto).

## Уровни потокобезопасности

В документации C API используются следующие уровни для описания гарантий потокобезопасности каждой функции. Уровни перечислены от наименее к наиболее безопасному.

### Несовместимый

Функция или операция, которую невозможно сделать безопасной для одновременного использования даже с внешней синхронизацией. Несовместимый код обычно обращается к глобальному состоянию несинхронизированным образом и должен вызываться только из одного потока в течение всего времени работы программы.

Пример: функция, которая изменяет общепроцессное состояние, например обработчики сигналов или переменные окружения, где параллельные вызовы из любых потоков, даже с внешней блокировкой, могут конфликтовать со средой выполнения или другими библиотеками.

### Совместимый

Функция или операция, которую можно безопасно вызывать из нескольких потоков *при условии*, что вызывающая сторона обеспечивает соответствующую внешнюю синхронизацию, например, удерживая [блокировку](https://python-all.ru/3.15/glossary.html#term-lock) на время каждого вызова. Без такой синхронизации параллельные вызовы могут привести к [состояниям гонки](https://python-all.ru/3.15/glossary.html#term-race-condition) или [гонкам данных](https://python-all.ru/3.15/glossary.html#term-data-race).

Пример: функция, которая читает или записывает данные объекта, внутреннее состояние которого не защищено блокировкой. Вызывающая сторона должна гарантировать, что никакие два потока не обращаются к одному и тому же объекту одновременно.

### Безопасный на разных объектах

Функция или операция, которую можно безопасно вызывать из нескольких потоков без внешней синхронизации, при условии, что каждый поток работает с **разным** объектом. Два потока могут вызывать функцию одновременно, но они не должны передавать один и тот же объект (или объекты, разделяющие общее внутреннее состояние) в качестве аргументов.

Пример: функция, которая изменяет поля структуры с помощью неатомарных записей. Два потока могут безопасно вызывать функцию каждый на своём экземпляре структуры, но параллельные вызовы на *одном и том же* экземпляре требуют внешней синхронизации.

### Безопасный на общих объектах

Функция или операция, безопасная для одновременного использования на **одном и том же** объекте. Реализация использует внутреннюю синхронизацию (например, [поблочные блокировки](https://python-all.ru/3.15/glossary.html#term-per-object-lock) или [критические секции](https://python-all.ru/3.15/c-api/synchronization.html#python-critical-section-api)) для защиты общего изменяемого состояния, поэтому вызывающей стороне не нужно предоставлять собственную блокировку.

Пример: [`PyList_GetItemRef()`](https://python-all.ru/3.15/c-api/list.html#c.PyList_GetItemRef) можно вызывать из нескольких потоков на одном и том же [`PyListObject`](https://python-all.ru/3.15/c-api/list.html#c.PyListObject) – он использует внутреннюю синхронизацию для сериализации доступа.

### Атомарный

Функция или операция, которая выглядит [атомарной](https://python-all.ru/3.15/glossary.html#term-atomic-operation) по отношению к другим потокам – она выполняется мгновенно с точки зрения других потоков. Это самая сильная форма потокобезопасности.

Пример: [`PyMutex_IsLocked()`](https://python-all.ru/3.15/c-api/synchronization.html#c.PyMutex_IsLocked) выполняет атомарное чтение состояния мьютекса и может вызываться из любого потока в любое время.

## Потокобезопасность для объектов списка

Чтение одного элемента из [`list`](https://python-all.ru/3.15/library/stdtypes.html#list) является [атомарным](https://python-all.ru/3.15/glossary.html#term-atomic-operation):

```python
lst[i]   # list.__getitem__
```

Следующие методы обходят список и используют [атомарные](https://python-all.ru/3.15/glossary.html#term-atomic-operation) чтения каждого элемента для выполнения своей функции. Это означает, что они могут возвращать результаты, на которые повлияли параллельные изменения:

```python
item in lst
lst.index(item)
lst.count(item)
```

Все перечисленные выше операции не приобретают [поблочных блокировок](https://python-all.ru/3.15/glossary.html#term-per-object-lock). Они не блокируют параллельные изменения. Другие операции, удерживающие блокировку, не помешают этим операциям наблюдать промежуточные состояния.

Все остальные операции, начиная с этого места, блокируются с помощью [поблочной блокировки](https://python-all.ru/3.15/glossary.html#term-per-object-lock).

Запись одного элемента через `lst[i] = x` безопасна для вызова из нескольких потоков и не повредит список.

Следующие операции возвращают новые объекты и выглядят [атомарными](https://python-all.ru/3.15/glossary.html#term-atomic-operation) для других потоков:

```python
lst1 + lst2    # объединяет два списка в новый список
x * lst        # повторяет lst x раз в новом списке
lst.copy()     # возвращает поверхностную копию списка
```

Следующие методы, которые работают только с одним элементом без необходимости сдвига, являются [атомарными](https://python-all.ru/3.15/glossary.html#term-atomic-operation):

```python
lst.append(x)  # добавить в конец списка, сдвиг не требуется
lst.pop()      # извлечь элемент из конца списка, сдвиг не требуется
```

Метод [`clear()`](https://python-all.ru/3.15/library/stdtypes.html#list.clear) также является [атомарным](https://python-all.ru/3.15/glossary.html#term-atomic-operation). Другие потоки не могут наблюдать удаление элементов.

Метод [`sort()`](https://python-all.ru/3.15/library/stdtypes.html#list.sort) не является [атомарным](https://python-all.ru/3.15/glossary.html#term-atomic-operation). Другие потоки не могут наблюдать промежуточные состояния во время сортировки, но список выглядит пустым на время сортировки.

Следующие операции могут позволить [безблокировочным](https://python-all.ru/3.15/glossary.html#term-lock-free) операциям наблюдать промежуточные состояния, поскольку они изменяют несколько элементов на месте:

```python
lst.insert(idx, item)  # сдвигает элементы
lst.pop(idx)           # idx не в конце списка, сдвигает элементы
lst *= x               # копирует элементы на месте
```

Метод [`remove()`](https://python-all.ru/3.15/library/stdtypes.html#list.remove) может допускать параллельные изменения, поскольку сравнение элементов может выполнять произвольный код Python (через [`__eq__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__eq__)).

[`extend()`](https://python-all.ru/3.15/library/stdtypes.html#list.extend) безопасно вызывать из нескольких потоков. Однако его гарантии зависят от переданного итерируемого объекта. Если это [`list`](https://python-all.ru/3.15/library/stdtypes.html#list), [`tuple`](https://python-all.ru/3.15/library/stdtypes.html#tuple), [`set`](https://python-all.ru/3.15/library/stdtypes.html#set), [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset), [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict) или [объект представления словаря](https://python-all.ru/3.15/library/stdtypes.html#dict-views) (но не их подклассы), то операция `extend` безопасна при параллельных изменениях итерируемого объекта. В противном случае создаётся итератор, который может быть параллельно изменён другим потоком. То же самое относится к конкатенации списка с другими итерируемыми объектами на месте при использовании `lst += iterable`.

Аналогично, присваивание срезу списка с помощью `lst[i:j] = iterable` безопасно вызывать из нескольких потоков, но `iterable` блокируется только в том случае, если он также является [`list`](https://python-all.ru/3.15/library/stdtypes.html#list) (но не его подклассом).

Операции, включающие множественные обращения, а также итерацию, никогда не являются атомарными. Например:

```python
# НЕ атомарно: чтение-изменение-запись
lst[i] = lst[i] + 1

# НЕ атомарно: проверка-затем-действие
if lst:
    item = lst.pop()

# НЕ потокобезопасно: итерация во время изменения
for item in lst:
    process(item)  # другой поток может изменить lst
```

Рассмотрите внешнюю синхронизацию при совместном использовании экземпляров [`list`](https://python-all.ru/3.15/library/stdtypes.html#list) между потоками.

## Потокобезопасность объектов dict

Создание словаря с помощью конструктора [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict) является атомарным, когда его аргумент – это `dict` или [`tuple`](https://python-all.ru/3.15/library/stdtypes.html#tuple). При использовании метода [`dict.fromkeys()`](https://python-all.ru/3.15/library/stdtypes.html#dict.fromkeys) создание словаря атомарно, когда аргумент – `dict`, `tuple`, [`set`](https://python-all.ru/3.15/library/stdtypes.html#set) или [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset).

Следующие операции и функции являются [безблокировочными](https://python-all.ru/3.15/glossary.html#term-lock-free) и [атомарными](https://python-all.ru/3.15/glossary.html#term-atomic-operation).

```python
d[key]       # dict.__getitem__
d.get(key)   # dict.get
key in d     # dict.__contains__
len(d)       # dict.__len__
```

Все остальные операции, начиная с этого момента, удерживают [блокировку объекта](https://python-all.ru/3.15/glossary.html#term-per-object-lock).

Запись или удаление одного элемента безопасно вызывать из нескольких потоков, и это не повредит словарь:

```python
d[key] = value        # записать
del d[key]            # удалить
d.pop(key)            # удалить и вернуть
d.popitem()           # удалить и вернуть последний элемент
d.setdefault(key, v)  # вставить, если отсутствует
```

Эти операции могут сравнивать ключи с помощью [`__eq__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__eq__), который может выполнять произвольный код Python. Во время таких сравнений словарь может быть изменён другим потоком. Для встроенных типов, таких как [`str`](https://python-all.ru/3.15/library/stdtypes.html#str), [`int`](https://python-all.ru/3.15/library/functions.html#int) и [`float`](https://python-all.ru/3.15/library/functions.html#float), которые реализуют `__eq__()` на C, базовая блокировка не освобождается во время сравнений, и это не вызывает проблем.

Следующие операции возвращают новые объекты и удерживают [блокировку объекта](https://python-all.ru/3.15/glossary.html#term-per-object-lock) на время выполнения операции:

```python
d.copy()      # возвращает поверхностную копию словаря
d | other     # объединяет два словаря в новый словарь
d.keys()      # возвращает новый объект представления dict_keys
d.values()    # возвращает новый объект представления dict_values
d.items()     # возвращает новый объект представления dict_items
```

Метод [`clear()`](https://python-all.ru/3.15/library/stdtypes.html#dict.clear) удерживает блокировку на всё время своего выполнения. Другие потоки не могут наблюдать удаление элементов.

Следующие операции блокируют оба словаря. Для [`update()`](https://python-all.ru/3.15/library/stdtypes.html#dict.update) и `|=` это применимо только в том случае, если другой операнд является [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict), который использует стандартный итератор dict (но не подклассы, переопределяющие итерацию). Для сравнения на равенство это относится к `dict` и его подклассам:

```python
d.update(other_dict)  # оба заблокированы, если other_dict – это dict
d |= other_dict       # оба заблокированы, если other_dict – это dict
d == other_dict       # оба заблокированы для dict и его подклассов
```

Все операции сравнения также сравнивают значения с помощью [`__eq__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__eq__), поэтому для невстроенных типов блокировка может быть освобождена во время сравнения.

[`fromkeys()`](https://python-all.ru/3.15/library/stdtypes.html#dict.fromkeys) блокирует как новый словарь, так и итерируемый объект, если итерируемый объект является именно [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict), [`set`](https://python-all.ru/3.15/library/stdtypes.html#set) или [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset) (не подклассами):

```python
dict.fromkeys(a_dict)      # блокирует оба
dict.fromkeys(a_set)       # блокирует оба
dict.fromkeys(a_frozenset) # блокирует оба
```

При обновлении из итерируемого объекта, не являющегося словарём, блокируется только целевой словарь. Итерируемый объект может быть параллельно изменён другим потоком:

```python
d.update(iterable)        # iterable не является dict: заблокирован только d
d |= iterable             # iterable не является dict: заблокирован только d
dict.fromkeys(iterable)   # iterable не является dict/set/frozenset: заблокирован только результат
```

Операции, включающие множественные обращения, а также итерации, никогда не являются атомарными:

```python
# НЕ атомарно: чтение-изменение-запись
d[key] = d[key] + 1

# НЕ атомарно: проверка-затем-действие (TOCTOU)
if key in d:
    del d[key]

# НЕ потокобезопасно: итерация во время изменения
for key, value in d.items():
    process(key)  # другой поток может изменить d
```

Чтобы избежать проблем TOCTOU (проверка-в-один-момент, использование-в-другой), используйте атомарные операции или обрабатывайте исключения:

```python
# Используйте pop() со значением по умолчанию вместо проверки с последующим удалением
d.pop(key, None)

# Или обработайте исключение
try:
    del d[key]
except KeyError:
    pass
```

Для безопасной итерации по словарю, который может быть изменён другим потоком, итерируйте по копии:

```python
# Сделайте копию для безопасной итерации
for key, value in d.copy().items():
    process(key)
```

Рассмотрите внешнюю синхронизацию при совместном использовании экземпляров [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict) между потоками.

## Потокобезопасность объектов set

Функция [`len()`](https://python-all.ru/3.15/library/functions.html#len) не использует блокировки и является [атомарной](https://python-all.ru/3.15/glossary.html#term-atomic-operation).

Следующая операция чтения является безблокировочной. Она не блокирует параллельные изменения и может наблюдать промежуточные состояния операций, которые удерживают блокировку объекта:

```python
elem in s    # set.__contains__
```

Эта операция может сравнивать элементы с помощью [`__eq__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__eq__), который может выполнять произвольный код Python. Во время таких сравнений множество может быть изменено другим потоком. Для встроенных типов, таких как [`str`](https://python-all.ru/3.15/library/stdtypes.html#str), [`int`](https://python-all.ru/3.15/library/functions.html#int) и [`float`](https://python-all.ru/3.15/library/functions.html#float), `__eq__()` не освобождает базовую блокировку во время сравнений, и это не вызывает проблем.

Все остальные операции, начиная с этого момента, удерживают блокировку на объект.

Добавление или удаление одного элемента безопасно вызывать из нескольких потоков и не повредит множество:

```python
s.add(elem)      # добавляет элемент
s.remove(elem)   # удаляет элемент, вызывает исключение, если отсутствует
s.discard(elem)  # удаляет элемент, если присутствует
s.pop()          # удаляет и возвращает произвольный элемент
```

Эти операции также сравнивают элементы, поэтому применимы те же соображения относительно [`__eq__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__eq__), что и выше.

Метод [`copy()`](https://python-all.ru/3.15/library/stdtypes.html#set.copy) возвращает новый объект и удерживает блокировку объекта на всё время выполнения, так что он всегда атомарен.

Метод [`clear()`](https://python-all.ru/3.15/library/stdtypes.html#set.clear) удерживает блокировку на всё время своего выполнения. Другие потоки не могут наблюдать удаление элементов.

Следующие операции принимают только [`set`](https://python-all.ru/3.15/library/stdtypes.html#set) или [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset) в качестве операндов и всегда блокируют оба объекта:

```python
s |= other                   # other должен быть set/frozenset
s &= other                   # other должен быть set/frozenset
s -= other                   # other должен быть set/frozenset
s ^= other                   # other должен быть set/frozenset
s & other                    # other должен быть set/frozenset
s | other                    # other должен быть set/frozenset
s - other                    # other должен быть set/frozenset
s ^ other                    # other должен быть set/frozenset
```

[`set.update()`](https://python-all.ru/3.15/library/stdtypes.html#set.update), [`set.union()`](https://python-all.ru/3.15/library/stdtypes.html#set.union), [`set.intersection()`](https://python-all.ru/3.15/library/stdtypes.html#set.intersection) и [`set.difference()`](https://python-all.ru/3.15/library/stdtypes.html#set.difference) могут принимать несколько итерируемых объектов в качестве аргументов. Все они перебирают все переданные итерируемые объекты и выполняют следующее:

> - **[`set.update()`](https://python-all.ru/3.15/library/stdtypes.html#set.update) и [`set.union()`](https://python-all.ru/3.15/library/stdtypes.html#set.union) блокируют оба объекта только когда**
>
>   другой операнд является [`set`](https://python-all.ru/3.15/library/stdtypes.html#set), [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset) или [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict).
> - **[`set.intersection()`](https://python-all.ru/3.15/library/stdtypes.html#set.intersection) и [`set.difference()`](https://python-all.ru/3.15/library/stdtypes.html#set.difference) всегда пытаются заблокировать**
>
>   все объекты.

[`set.symmetric_difference()`](https://python-all.ru/3.15/library/stdtypes.html#set.symmetric_difference) пытается заблокировать оба объекта.

У обновлённых вариантов перечисленных выше методов также есть некоторые различия между ними:

> - **[`set.difference_update()`](https://python-all.ru/3.15/library/stdtypes.html#set.difference_update) и [`set.intersection_update()`](https://python-all.ru/3.15/library/stdtypes.html#set.intersection_update) пытаются**
>
>   блокировать все объекты по одному.
> - **[`set.symmetric_difference_update()`](https://python-all.ru/3.15/library/stdtypes.html#set.symmetric_difference_update) блокирует аргументы только если они являются**
>
>   типа [`set`](https://python-all.ru/3.15/library/stdtypes.html#set), [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset) или [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict).

Следующие методы всегда пытаются заблокировать оба объекта:

```python
s.isdisjoint(other)          # оба заблокированы
s.issubset(other)            # оба заблокированы
s.issuperset(other)          # оба заблокированы
```

Операции, включающие множественные обращения, а также итерации, никогда не являются атомарными:

```python
# НЕ атомарно: проверка-затем-действие
if elem in s:
      s.remove(elem)

# НЕ потокобезопасно: итерация во время изменения
for elem in s:
      process(elem)  # другой поток может изменить s
```

Рекомендуется использовать внешнюю синхронизацию при совместном использовании экземпляров [`set`](https://python-all.ru/3.15/library/stdtypes.html#set) между потоками. Подробнее см. [Python support for free threading](https://python-all.ru/3.15/howto/free-threading-python.html#freethreading-python-howto).

## Потокобезопасность объектов bytearray

> Функция [`len()`](https://python-all.ru/3.15/library/functions.html#len) не использует блокировки и является [атомарной](https://python-all.ru/3.15/glossary.html#term-atomic-operation).
>
> Конкатенация и сравнения используют буферный протокол, который предотвращает изменение размера, но не удерживает блокировку для каждого объекта. Эти операции могут наблюдать промежуточные состояния параллельных изменений:
>
> ```python
> ba + other    # может наблюдать конкурентные записи
> ba == other   # может наблюдать конкурентные записи
> ba < other    # может наблюдать конкурентные записи
> ```
>
> Все остальные операции, начиная с этого момента, удерживают блокировку на объект.
>
> Чтение одного элемента или среза безопасно вызывать из нескольких потоков:
>
> ```python
> ba[i]        # bytearray.__getitem__
> ba[i:j]      # срез
> ```
>
> Следующие операции безопасно вызывать из нескольких потоков, и они не повредят bytearray:
>
> ```python
> ba[i] = x         # запись одного байта
> ba[i:j] = values  # запись среза
> ba.append(x)      # добавление одного байта
> ba.extend(other)  # расширение итерируемым объектом
> ba.insert(i, x)   # вставка одного байта
> ba.pop()          # удаление и возврат последнего байта
> ba.pop(i)         # удаление и возврат байта по индексу
> ba.remove(x)      # удаление первого вхождения
> ba.reverse()      # обращение на месте
> ba.clear()        # удаление всех байтов
> ```
>
> Присваивание среза блокирует оба объекта, когда *значения* является [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray):
>
> ```python
> ba[i:j] = other_bytearray  # оба заблокированы
> ```
>
> Следующие операции возвращают новые объекты и удерживают блокировку на объект на всё время выполнения:
>
> ```python
> ba.copy()     # возвращает поверхностную копию
> ba * n        # повтор в новый bytearray
> ```
>
> Проверка принадлежности удерживает блокировку на всё время выполнения:
>
> ```python
> x in ba       # bytearray.__contains__
> ```
>
> Все остальные методы bytearray (такие как [`find()`](https://python-all.ru/3.15/library/stdtypes.html#bytearray.find), [`replace()`](https://python-all.ru/3.15/library/stdtypes.html#bytearray.replace), [`split()`](https://python-all.ru/3.15/library/stdtypes.html#bytearray.split), [`decode()`](https://python-all.ru/3.15/library/stdtypes.html#bytearray.decode) и т.д.) удерживают блокировку на объект на всё время своего выполнения.
>
> Операции, включающие множественные обращения, а также итерации, никогда не являются атомарными:
>
> ```python
> # НЕ атомарно: проверка-затем-действие
> if x in ba:
>     ba.remove(x)
>
> # НЕ потокобезопасно: итерация во время изменения
> for byte in ba:
>     process(byte)  # другой поток может изменить ba
> ```
>
> Для безопасной итерации по bytearray, который может быть изменён другим потоком, выполняйте итерацию по копии:
>
> ```python
> # Сделайте копию для безопасной итерации
> for byte in ba.copy():
>     process(byte)
> ```
>
> Рекомендуется использовать внешнюю синхронизацию при совместном использовании экземпляров [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray) между потоками. Подробнее см. [Python support for free threading](https://python-all.ru/3.15/howto/free-threading-python.html#freethreading-python-howto).

## Потокобезопасность объектов memoryview

Объекты [`memoryview`](https://python-all.ru/3.15/library/stdtypes.html#memoryview) предоставляют доступ к внутренним данным базового объекта без копирования. Потокобезопасность зависит как от самого memoryview, так и от экспортёра буфера базового объекта.

Реализация memoryview использует атомарные операции для отслеживания собственных экспортов в [сборке со свободной многопоточностью](https://python-all.ru/3.15/glossary.html#term-free-threaded-build). Создание и освобождение memoryview потокобезопасны. Доступ к атрибутам (например, [`shape`](https://python-all.ru/3.15/library/stdtypes.html#memoryview.shape), [`format`](https://python-all.ru/3.15/library/stdtypes.html#memoryview.format)) читает поля, которые неизменны на время существования memoryview, поэтому одновременное чтение безопасно, пока memoryview не был освобождён.

Однако фактические данные, доступ к которым осуществляется через memoryview, принадлежат базовому объекту. Одновременный доступ к этим данным безопасен только в том случае, если базовый объект это поддерживает:

- Для неизменяемых объектов, таких как [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes), одновременное чтение через несколько memoryview безопасно.
- Для изменяемых объектов, таких как [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray), чтение и запись одной и той же области памяти из нескольких потоков без внешней синхронизации небезопасны и могут привести к повреждению данных. Обратите внимание, что даже memoryviews, доступные только для чтения, изменяемых объектов не предотвращают гонку данных, если базовый объект изменяется из другого потока.

```python
# НЕ безопасно: конкурентные записи в один буфер
data = bytearray(1000)
view = memoryview(data)
# Поток 1: view[0:500] = b'x' * 500
# Поток 2: view[0:500] = b'y' * 500
```

```python
# Безопасно: используется блокировка для конкурентного доступа
import threading
lock = threading.Lock()
data = bytearray(1000)
view = memoryview(data)

with lock:
    view[0:500] = b'x' * 500
```

Изменение размера или перераспределение базового объекта (например, вызов [`bytearray.resize()`](https://python-all.ru/3.15/library/stdtypes.html#bytearray.resize)) во время экспорта memoryview вызывает исключение [`BufferError`](https://python-all.ru/3.15/library/exceptions.html#BufferError). Это действует независимо от потоков.
