Возможно, вам нужно немного подумать о том, что значит быть потокобезопасным.Подумайте, написали ли вы этот код вместо этого:
class SomeSharedData(object):
def __init__(self):
self.errors = 0
Этот код точно такой же потокобезопасный, как и код, который вы опубликовали.Присвоение значения атрибуту является потокобезопасным в Python: значение всегда присваивается;оно может или не может быть перезаписано другим значением, назначенным из другого потока, но вы всегда получаете одно или другое значение, никогда не смешивая их.Аналогичным образом, доступ к атрибуту дает вам текущее значение.
Если ваш код разрывается, то, как вы сказали в исходной или упрощенной версии, строка, такая как:
shared.errors += 1
, неПотокобезопасен, но в этом весь смысл обеспечения безопасности вашего кода, это то, на что нужно обращать внимание, а не просто get / set.
Ответ на вопрос в комментарии:
Простое назначение в Python - это просто повторное связывание имени (не создание копии) и гарантированное атомарное;Вы получаете одно значение или другое.Однако присвоение атрибуту (или переменной с подпиской) может быть переопределено, как в вашем свойстве выше.В этом случае присвоение атрибута может потенциально нарушиться.Таким образом, ответ заключается в том, что присвоение атрибута обычно безопасно, но не в том случае, если оно было переопределено свойством или setattr или аналогичным.
Кроме того, если заменяется старое значениекласс Python с деструктором, или что-то, что содержит класс Python с деструктором, тогда код деструктора может выполняться в середине присваивания.Python по-прежнему будет гарантировать, что его собственные структуры данных не будут повреждены (поэтому вы никогда не должны получить segfault), но он не будет делать то же самое для ваших собственных.Очевидным решением для этого никогда не является определение del для любого из ваших классов.