Ответ
Атомарная операция — это операция, которая выполняется как единое целое, без возможности прерывания или вмешательства других потоков/процессов. Либо она выполняется полностью, либо не выполняется вовсе.
В Python, из-за Global Interpreter Lock (GIL), некоторые операции, которые кажутся атомарными (например, присваивание ссылки на объект), на самом деле являются таковыми на уровне байт-кода. Однако составные операции, такие как counter += 1
(которая состоит из чтения значения, инкремента и записи нового значения), не являются атомарными и могут привести к некорректным результатам в многопоточной среде без синхронизации.
Для обеспечения атомарности составных операций в Python используются механизмы синхронизации, такие как блокировки (locks).
Пример атомарной операции с использованием threading.Lock
:
В этом примере мы хотим безопасно инкрементировать счетчик из нескольких потоков. Операция counter += 1
сама по себе не атомарна, но мы делаем ее атомарной, обернув в блок, защищенный threading.Lock
.
import threading
counter = 0
lock = threading.Lock() # Создаем объект блокировки
def increment_counter():
"""Функция для инкремента счетчика в потоке."""
global counter
with lock: # Захватываем блокировку перед доступом к общему ресурсу
# Этот блок кода выполняется атомарно:
# Ни один другой поток не сможет войти в этот блок,
# пока текущий поток не выйдет из него.
counter += 1
# Блокировка автоматически освобождается при выходе из 'with' блока
# Создаем и запускаем несколько потоков
threads = []
for _ in range(1000): # Например, 1000 инкрементов
t = threading.Thread(target=increment_counter)
threads.append(t)
t.start()
# Ожидаем завершения всех потоков
for t in threads:
t.join()
print(f"Финальное значение счетчика: {counter}") # Гарантированно выведет 1000
Без использования lock
, финальное значение counter
было бы непредсказуемым и, скорее всего, меньше 1000 из-за гонок данных. Блокировка гарантирует, что операция чтения, инкремента и записи для counter
выполняется как единое целое, предотвращая одновременный доступ и обеспечивая корректный результат.