Из-за того, каким образом интерпретатор Python использует GIL для синхронизации доступа к виртуальной машине, ни для каких инструкций высокого уровня не гарантируется выполнение инструкции до конца до переключения на другой поток, но оно гарантируется для всех инструкций в байт-коде. Инструкции в байт-коде являются неделимыми, поэтому некоторые операции в языке Python обеспечивают безопасную работу с потоками. Такие операции называются атомарными, потому что их выполнение не может быть прервано — и при их использовании не требуется задействовать блокировки или очереди, чтобы избежать проблем, связанных с одновременными изменениями. Например, к моменту написания этих строк в стандартной реализации C Python выполняются атомарно: метод list.append, операции извлечения и некоторые операции присваивания значений переменным, обращение к элементам списков, ключам словарей и атрибутам объектов, а также некоторые другие операции. Другие операции, такие как x = x+1 (и вообще любые операции, при выполнении которых происходит чтение данных, их изменение и запись обратно), — нет.
Однако, как уже отмечалось выше, не следует полагаться на эти особенности, потому что они требуют глубокого понимания внутренней реализации интерпретатора и могут изменяться от версии к версии. На самом деле, набор атомарных операций может существенно измениться с введением более свободной от ограничений реализации потоков. На практике проще использовать блокировки для доступа ко всем глобальным переменным и общим объектам, чем пытаться запомнить, какие операции могут или не могут быть безопасными при одновременном использовании их в нескольких потоках выполнения.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011