В Python (Django), как я могу остановить доступ к глобальной структуре данных словаря, когда она обновляется? - PullRequest
2 голосов
/ 18 декабря 2009

В django при обновлении структуры данных глобального словаря я хочу заблокировать доступ к нему другим запросом. Я планирую иметь функцию-оболочку для обновления, доступа и синхронизации. Исходя из фона Java! Есть указатели?

Ответы [ 2 ]

2 голосов
/ 19 декабря 2009

Несколько расширив пример LockableDict, чтобы сделать его немного более надежным, вы можете использовать настоящий Lock:

class LockableDict(dict):
    def __init__(self, *args, **kwargs):
        from threading import Lock
        self.lock = Lock()
        dict.__init__(self, *args, **kwargs)

    @property
    def locked(self):
        return self.lock.locked()

    def lock(self):
        self.lock.acquire()

    def unlock(self):
        self.lock.release()

# and then
my_dict = LockableDict({1:2, 3:4})
my_dict.lock()
# do modifications
my_dict.unlock()
1 голос
/ 18 декабря 2009

Один интересный вариант - создать класс Lockable DIctionary, который будет сам блокироваться в зависимости от фрейма exection вызывающего. : -)

Самоанализ Python позволяет это сделать - и в зависимости от ваших потребностей это может подойти - (вы должны были бы поймать исключение, возникающее в тех местах, где вы хотите использовать значение, хотя - Я не использую Django, поэтому я не знаю, используют ли повторные запросы потоки - если да, (а не асинхронный ответ по одному потоку для всех запросов), вы можете заменить возникшее на некоторое время исключение - sleep - retry цикл.

from inspect import stack

class DictLocked(Exception):
    pass

class LockableDict(dict):
    def __init__(self, *args, **kw):
        dict.__init__(self, *args, **kw)
        self.locked = False
        self.locker = None
    def start_update(self):
        print stack()
        self.locked = True
        #Holds the code frame responsible for locking
        self.locker = stack()[1][0]
    def finish_update(self):
        self.locked = False

    def __getitem__(self, item):
        print stack()
        if self.locked:
            if stack()[1][0] != self.locker:
                raise DictLocked("Dictionary locked")
        return dict.__getitem__(self, item)

    def __setitem__(self, item, value):
        if self.locked:
            if stack()[1][0] != self.locker:
                raise DictLocked("Dictionary locked")
        return dict.__setitem__(self, item, value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...