python实例类使用同步锁

多线程程序最令人头疼的便是各种锁,写起来麻烦也容易出错。 还好Python中有装饰器这种方便的神器存在,我们只需像单线程一样写程序 ,然后在外边包上同步锁装饰器就ok了。比如:

import threading
 
def sync(lock):
    def syncWithLock(fn):
        def newFn(*args,**kwargs):
            lock.acquire()
            try:
                return fn(*args,**kwargs)
            finally:
                lock.release()
        newFn.func_name = fn.func_name
        newFn.__doc__ = fn.__doc__
        return newFn
    return syncWithLock
 
lock = threading.Lock()
     
@sync (lock)
def fn():
    global x
    for i in range(10):
        x+=1
     
if __name__ ==  "__main__":
    x = 0
     
    th = threading.Thread(target=fn)
    th2 = threading.Thread(target=fn)
    th3 = threading.Thread(target=fn)
     
    th.start()
    th2.start()
    th3.start()
     
    th.join()
    th2.join()
    th3.join()
     
    print x#30

如此,我们便可以派出多个线程来执行fn方法,而不用担心出现数据出错。然而有时候我们需要对实例方法加锁,一般来说该如何写呢?

class Test(object):
    def __init__(self):
        self.lock = threading.Lock()
     
    @sync (self.lock)
    def fn(self):
        pass

然而很遗憾,@sync(self.lock)里的self并无所指,而我们又无法得到实例对象本身的引用。很头疼,然而python的动态语言特性又使我们可以通过一些特别的方法来实现目的,目前我是这么做的:

class Test(object):
    def __init__(self):
        self.lock = threading.Lock()
        self.__decFns()
     
    def __decFns(self):
        @sync (self.lock)
        def __fn():
            pass
        self.fn = __fn

我们编写了一个帮助函数__decFns,用来帮助我们间接实现对实例方法的加锁,在__decFns里我们就可以获取实例的引用self进行加锁,然后把相应的方法绑定到方法接口供外部使用。 虽然解决了问题,但是总觉的不太好看,读者若有更好思路欢迎讨论。


你可能感兴趣的:(python实例类使用同步锁)