Какие операции в Python являются потокобезопасными?Python

Программы на Python
Ответить
Anonymous
 Какие операции в Python являются потокобезопасными?

Сообщение Anonymous »

Я пытаюсь понять, почему некоторые конкретные фрагменты кода ведут себя как потокобезопасные.
Есть страница часто задаваемых вопросов по Python, на которой указано, какие мутации считаются потокобезопасными (хотя я до сих пор не понимаю почему здесь атомарность подразумевает потокобезопасность)
Есть также страница глоссария, в которой немного рассказывается о GIL и говорится:

Этот [GIL] упрощает реализацию CPython путем создания объектной модели (включая важные встроенные типы, такие как dict

Итак, мое нынешнее понимание следующее:
  • GIL гарантирует, что в любой момент времени выполняются только инструкции одной виртуальной машины (не Python).
  • Некоторые операции над встроенными типами декомпилируются ровно в один байт-код. инструкцию, которую можно считать потокобезопасной (в данном контекст)
Но это не соответствует тому, что я вижу. Следующая функция Python:

Код: Выделить всё

def inc(stats):
stats["ok"] = stats["ok"] + 1
декомпилируется в (под Python 3.10.14 (main, 19 марта 2024, 21:46:16) [Clang 15.0.0 (clang-1500.3.9.4)] на darwin
код>)

Код: Выделить всё

  0 LOAD_FAST                0 (stats)
2 LOAD_CONST               1 ('ok')
4 BINARY_SUBSCR
6 LOAD_CONST               2 (1)
8 BINARY_ADD
10 LOAD_FAST                0 (stats)
12 LOAD_CONST               1 ('ok')
14 STORE_SUBSCR
16 LOAD_CONST               0 (None)
18 RETURN_VALUE
где мы ясно видим, что операция разбита на три соответствующие инструкции байт-кода (get add set) (

Код: Выделить всё

BINARY_SUBSCR
, BINARY_ADD, STORE_SUBSCR).
Несмотря на это, многократный запуск этой функции с использованием concurrent.futures.ThreadPoolExecutor всегда дает согласованный результат. результаты (т. е. отсутствие условий гонки)
То же самое происходит и с другими подозрительно небезопасными операциями, такими как x = x + 1 (которые также дают согласованные результаты)
Если я правильно понимаю, иногда следует ожидать состояния гонки.
Я подозреваю одно или несколько из следующих событий:
  • Мое понимание неверно.
  • В CPython предусмотрена специальная обработка словарных операций.
  • Эта операция выполняется достаточно быстро, поэтому Планировщик потоков Python не может вытеснить поток в середине выполнения оператора (не bytecode)
UPD: я попробовал разбить stats["ok"] = stats["ok"] + 1 на два оператора через промежуточную переменную и вставку коротких снов между этими двумя и наблюдаемыми гонками данных. Таким образом, третья интуиция, вероятно, верна, и stats["ok"] = stats["ok"] + 1 также по своей сути не является потокобезопасным, поскольку также состоит из нескольких инструкций байт-кода.

Подробнее здесь: https://stackoverflow.com/questions/792 ... -in-python
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»