13

I was thinking about using a class variable as a thread lock, since I don't like to define a lock within the global variables and also want to prevent deadlock. Does this actually work? Example:

import threading

class A(object):
    lock = threading.Lock()
    a = 1

    @classmethod
    def increase_a(cls):
        with cls.lock:
            cls.a += 1

Considering I would not re-assign the A.lock variable somewhere inside or outside the class, my assumption would be that it is treated the same as a global lock? Is this correct?

Torsten Engelbrecht
  • 13,318
  • 4
  • 46
  • 48
  • Bad idea to use it since inheritance problems. – Chameleon Apr 21 '14 at 11:03
  • Yes, I will elaborate: A.lock is initialized by A metaclass (as default type) - all classes inherited from A will share the same lock so `class B(A): pass` be `A.lock == B.lock` if `B` will use `A.increase` it will lead to lock since double `A.lock.aquire(); B.lock.aquire() # deadlock A.lock is B.lock`. Valid pattern is replace metaclass (defualt type) with class initializing lock this will allow thread safe inheritance. Do not try use in this case RLock since it will lead to more complex bugs. – Chameleon Apr 22 '14 at 11:09
  • Read the answer and comments later http://stackoverflow.com/questions/23196437 – Chameleon Apr 22 '14 at 11:26
  • Ok, got it. In this particular use case I was not intending to inherit from this class. Quite a useful tip though. – Torsten Engelbrecht Apr 22 '14 at 12:27

1 Answers1

4

Sure. You want to have a reference to the lock that's easy to get at, and storing it on the class is just fine.

You may want to call it __lock (to activate name mangling) though, so it's not confused with locks in subclasses of A

John La Rooy
  • 295,403
  • 53
  • 369
  • 502