Другие ответы уже правильно адресованы тем, что, по-видимому, является вашим актуальным вопросом:
Означает ли это, что я могу или не могу изменить элементы в словаре, повторяя его?
Объясняя, что безопасность потоков не имеет ничего общего с проблемой, и в любом случае, нет, вы не можете изменить dict при его итерации.
Однако заголовок вашего вопроса - это о безопасности потоков, и вы начинаете с:
Некоторые утверждают, что словарь Python является потокобезопасным
Я не знаю, кто "некоторые "есть, но, если они заявили, что (вместо того, чтобы вы неправильно поняли, что они заявили ;-) без высокой квалификации, они ошибаются.
Некоторые операции, те, которые нене меняйте набор ключей в dict, так как в текущих реализациях CPython он является поточно-ориентированным, но вы должны , а не рассчитывать на это, если только вы не строго контролируете версию Python, в которой ваш код будетвыполнить, потому что такая безопасность потока не гарантируется спецификацией языка Python, и поэтому другие реализации, включая будущие версии CPython, могут не предлагать его.
Если каждый поток только «читает» диктовку (индексирует ее, делает циклна нем и т. д.), и никакой поток не выполняет какого-либо присваивания или удаления на нем, тогда эта ситуация безопасна в текущих реализациях CPython;на самом деле, если какой-то поток назначает новое значение ключу, который уже присутствовал, это также потокобезопасно (другие потоки могут видеть предыдущее значение для этого ключа или следующее, в зависимости от того, как потоки были синхронизированы,но в текущих реализациях CPython не будет ни сбоев, ни тупиков, ни появления сумасшедших значений из ниоткуда).
Однако такая операция, как d[k] += 1
(при условии, что k ранее присутствовал, и егозначение число) не правильно говоря, потокобезопасен (больше, чем другой случай +=
!), потому что его можно рассматривать как d[k] = d[k] + 1
- может произойти, что двапотоки в состоянии гонки оба читают старое значение d[k]
, затем увеличивают его на единицу и сохраняют одно и то же новое значение в слоте ... таким образом, общий эффект заключается в увеличении его только на единицу, а не на два, так какобычно происходит.
Возвращаясь к вашему другому вопросу ... "только чтение" dict, и присваивают новые значения клавишам, которые уже существовали в dict,также то, что вы можете делать в теле цикла, который повторяется в dict - вы не можете изменить набор ключей в dict (вы не можете добавить ни один ключ, ни удалить любой ключ), но конкретную операциюдопускается установка нового значения для существующего ключа.Разрешенные операции в этом случае включают +=
, что было бы проблематично в поточной ситуации.Например:
>>> d = dict.fromkeys(range(5), 0)
>>> for k in d: d[k] += 1
...
>>> d
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1}
и это поведение гарантируется стандартизированной семантикой Python, поэтому все реализации языка должны его сохранять.