I
Irmen de Jong
Hi,
I've developed the Metaclass below, because I needed a way
to make a bunch of classes thread-safe.
I didn't want to change every method of the class by adding
lock.aqcuire()..lock.release() around the existing code.
So I made a metaclass that essentially replaces every method
of a class with a 'wrapper' method, that does the locking,
invocation, unlocking.
Is this the right approach? It seems to work fine. But I have
very little experience with metaclass programming, so I'd like
to hear some feedback.
Thanks !!
--Irmen de Jong.
# ---- source below ----
from types import FunctionType
from threading import RLock
class ThreadSafeMethodsMetaClass(type):
def __new__(meta, name, bases, dict):
meta.convert_methods(dict)
return super(ThreadSafeMethodsMetaClass, meta).__new__(meta, name, bases, dict)
def makeThreadsafeMethod(func):
def threadsafemethod(self, *args, **kwargs):
self._monitor_lockObj.acquire()
print ">>got lock"
try:
return func(self, *args, **kwargs)
finally:
self._monitor_lockObj.release()
print "<<released lock"
return threadsafemethod
makeThreadsafeMethod = staticmethod(makeThreadsafeMethod)
def convert_methods(cls, dict):
methods=[ v for k,v in dict.iteritems() if isinstance(v, FunctionType) ]
for m in methods:
dict[m.__name__]=cls.makeThreadsafeMethod(m)
dict["_monitor_lockObj"] = RLock()
convert_methods = classmethod(convert_methods)
class MyClass(object):
__metaclass__=ThreadSafeMethodsMetaClass
def __init__(self):
print "init!"
def method(self, a1, a2):
print a1,a2
m=MyClass()
m.method("irmen",42)
I've developed the Metaclass below, because I needed a way
to make a bunch of classes thread-safe.
I didn't want to change every method of the class by adding
lock.aqcuire()..lock.release() around the existing code.
So I made a metaclass that essentially replaces every method
of a class with a 'wrapper' method, that does the locking,
invocation, unlocking.
Is this the right approach? It seems to work fine. But I have
very little experience with metaclass programming, so I'd like
to hear some feedback.
Thanks !!
--Irmen de Jong.
# ---- source below ----
from types import FunctionType
from threading import RLock
class ThreadSafeMethodsMetaClass(type):
def __new__(meta, name, bases, dict):
meta.convert_methods(dict)
return super(ThreadSafeMethodsMetaClass, meta).__new__(meta, name, bases, dict)
def makeThreadsafeMethod(func):
def threadsafemethod(self, *args, **kwargs):
self._monitor_lockObj.acquire()
print ">>got lock"
try:
return func(self, *args, **kwargs)
finally:
self._monitor_lockObj.release()
print "<<released lock"
return threadsafemethod
makeThreadsafeMethod = staticmethod(makeThreadsafeMethod)
def convert_methods(cls, dict):
methods=[ v for k,v in dict.iteritems() if isinstance(v, FunctionType) ]
for m in methods:
dict[m.__name__]=cls.makeThreadsafeMethod(m)
dict["_monitor_lockObj"] = RLock()
convert_methods = classmethod(convert_methods)
class MyClass(object):
__metaclass__=ThreadSafeMethodsMetaClass
def __init__(self):
print "init!"
def method(self, a1, a2):
print a1,a2
m=MyClass()
m.method("irmen",42)