Если в моем веб-приложении на python есть @staticmethod, нужно ли защищать его с помощью threading.RLock ()? - PullRequest
3 голосов
/ 31 марта 2012

У меня есть веб-приложение, встроенное в python, работающее на сервере вставки. Если я объявил @staticmethod, который присваивает состояние переменным в методе, нужно ли мне защищать его, например, threading.RLock () (или есть лучший способ), чтобы предотвратить множественные HTTP-запросы (я предполагаю вставить как сервер содержит какой-то пул потоков для обслуживания входящих запросов) от вмешательства в состояние друг друга?

Я должен указать, что я использую Grok в качестве моей платформы.

так -

@staticmethod
def doSomeStuff():
 abc = 1
 ...some code...
 abc = 5

Учитывая вышеизложенное, является ли потокобезопасным внутри grok / paste между потоками (опять же, при условии, что запросы обрабатываются в потоках?)

1 Ответ

2 голосов
/ 31 марта 2012

Локальные переменные создаются для каждого вызова метода отдельно, независимо от того, статический ли это метод, метод класса, нестатический метод или автономная функция, так же, как в Java. Если вы явно не скопируете ссылки на эти объекты где-то за пределами, чтобы они пережили метод и могли быть доступны из других потоков, вам не нужно ничего блокировать.

Например, это безопасно, если CoolClass не использует какое-либо общее состояние между экземплярами:

def my_safe_method(*args):
    my_cool_object = CoolClass()
    my_cool_object.populate_from_stuff(*args)
    return my_cool_object.result()

Вероятно, это небезопасно, поскольку ссылка на объект может совместно использоваться потоками (зависит от того, что делает get_cool_inst):

def my_suspicious_method(*args):
    my_cool_object = somewhere.get_cool_inst()
    my_cool_object.populate_from_stuff(*args)
    # another thread received the same instance
    # and modified it
    # (my_cool_object is still local, but it's a reference to a shared object)
    return my_cool_object.result()

Это также может быть небезопасно, если publish поделится ссылкой:

def my_suspicious_method(*args):
    my_cool_object = CoolClass()
    # puts somewhere into global namespace, other threads access it
    publish(my_cool_object) 
    my_cool_object.prepare(*args)
    # another thread modifies it now
    return my_cool_object.result()

РЕДАКТИРОВАТЬ: Пример кода, который вы предоставили, является полностью потокобезопасным, @staticmethod ничего не изменил в этом отношении.

...