как я могу заблокировать весь класс - PullRequest
0 голосов
/ 27 августа 2011

У меня есть следующий псевдокод:

class A:
    mutex lockForB

class B:
    def __init__(self, A): //the type of A is class A
        lock(A.lockForB)
        # ...
        unlock(A.lockForB)

    # other function have the same locking

Я понимаю, что с другой стороны очень плохая идея использовать такой дизайн, но если я создам блокировку внутри класса B, я не смогу установить блокировку для создателя класса B. Есть ли какой-нибудь лучший дизайн для этого? Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 27 августа 2011

Понятия не имею, чего вы пытаетесь достичь. Маловероятно, что блокировка на уровне класса - это то, что вам нужно, но ваш псевдокод не так уж далек от реального кода, поэтому я просто заполню пробелы. Честно говоря, без какой-либо идеи, к чему вы пытаетесь синхронизировать доступ, вам будет сложно помочь.

class A:
    lockForB = threading.RLock()

class B:
    def __init__(self): 
        with A.lockForB:
            # do init stuff

    def othermethod(self):
        with A.lockForB:
            # do other stuff

Так что этот код будет работать. lockForB - это просто атрибут уровня класса на A, поэтому он используется всеми экземплярами A. Однако в тех случаях, когда я видел, что люди используют блокировки на уровне класса, подобные этим, обычно это предотвращает помещение класса, которому принадлежит блокировка, в несогласованное состояние, когда у вас есть 2, казалось бы, не связанных класса, совместно использующих блокировку.

Без контекста, который поможет понять, к чему вы пытаетесь синхронизировать доступ, очень сложно сказать вам, почему это не может быть написано так:

class C:
    lock = threading.RLock()
    def __init__(self):
        with self.lock:
            # do stuff
    def othermethod(self):
        with self.lock:
            # do other stuff
1 голос
/ 27 августа 2011

В общем, вы должны устанавливать блокировки только вокруг границ критических секций или использования общих ресурсов.Вы должны рассмотреть, что именно вы пытаетесь защитить от одновременного доступа, и защитить его.Если, например, у класса A есть Очередь, в которую помещаются и считываются элементы, то вам следует защищать доступ к этому конкретному ресурсу.Поскольку ООП диктует, что к этому виду ресурсов должны обращаться только методы класса, его должен защищать только класс A:

class A(object):
    def __init__(self, *args, **kws):
        # do the initialization
        self._my_queue = Queue()
        self._lock = Lock()

    def do_something(self):
        # do initial calculations
        self._lock.acquire()
        item = self._my_queue.get()
        self._lock.release()
        # do other things

Следовательно, класс B должен вызывать методы класса A, и он будет безопасным для потоков.Если у класса B есть свои критические секции, то вполне можно использовать более одной блокировки:

class B(object):
    def __init__(self, *args, **kws):
        # do the initialization
        self._lock = Lock()
        self.a = A()

    def do_something_with_a(self):
        # initial calculations
        self._lock.acquire()
        # Critical section
        result = self.a.do_something()
        # do something with result
        self._lock.release()
        # continue the code

Таким образом, каждый класс защищает свои критические секции и общие ресурсы, и нет необходимости нарушать интерфейс класса.

Если вам нужно защитить C'or класса, то вам нужна либо глобальная блокировка для модуля, созданная и инициализированная вне области действия класса, либо добавление блокировки к объекту Class (например,статический член в C ++ и Java), а не сам экземпляр:

class B(object):
    def __init__(self, *args, **kws):
        if not hasattr(self.__class__, "_lock"):
            self.__class__._lock = Lock()
        # works with Python 2.6+ for earlier version use try-finally
        with self.__class__._lock: 
            # Your initialization

Это защитит ваш C'tor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...